Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 递归和非递归合并排序算法在时间/空间复杂度上是否存在差异?_Java_Algorithm_Sorting_Recursion_Mergesort - Fatal编程技术网

Java 递归和非递归合并排序算法在时间/空间复杂度上是否存在差异?

Java 递归和非递归合并排序算法在时间/空间复杂度上是否存在差异?,java,algorithm,sorting,recursion,mergesort,Java,Algorithm,Sorting,Recursion,Mergesort,我使用分治方法实现了一个合并排序算法,其中一个数组被分成两个子数组 在我的代码中,我使用插入排序算法对合并排序中的子数组进行排序。这是正确的方法还是我必须使用不同的排序方法在合并排序中对子数组进行排序 关于对合并排序算法的理解,一切都很清楚,但是在实现合并排序时,如何在不使用递归策略的情况下将数组划分为n个子数组呢 递归还是非递归是实现合并排序的有效方法 下面是我在github中的代码片段: 我从实现的角度理解,我的代码是错误的,因为我只将数组划分为两个子数组,而不是n个子数组 从算法实现的角

我使用分治方法实现了一个合并排序算法,其中一个数组被分成两个子数组

在我的代码中,我使用插入排序算法对合并排序中的子数组进行排序。这是正确的方法还是我必须使用不同的排序方法在合并排序中对子数组进行排序

关于对合并排序算法的理解,一切都很清楚,但是在实现合并排序时,如何在不使用递归策略的情况下将数组划分为n个子数组呢

递归还是非递归是实现合并排序的有效方法

下面是我在github中的代码片段:

我从实现的角度理解,我的代码是错误的,因为我只将数组划分为两个子数组,而不是n个子数组

从算法实现的角度清楚理解合并排序所需的任何帮助

代码如下:

package com.algorithms.sort;
公共类合并排序{
公共静态整数[]增加(整数[]arr){
int[]结果=新int[arr.length];
int q=阵列长度/2;
System.out.println(“q:+q”);
int[]左=新int[q];
int[]right=新的int[q];
对于(int i=0;i
关于空间复杂性,实现可能因您的数据结构选择而异。
递归的
如果选择阵列:
空间复杂度:N log N
如果选择“链接列表”:
空间复杂度为O(1)
在迭代中:
如果选择阵列:
空间复杂度:N
(根据您的实现,它是O(N log N),因为您在每个分割状态下创建了一个新的子数组,
若要将其缩减为O(n),应使用一个额外数组作为原始数组的大小,并使用索引)
如果选择“链接列表”:
空间复杂度为O(1)

正如您所见,链表最适合排序。 除此之外,由于函数框架的创建,基于编程语言,递归可能会消耗比预期更多的内存


比优化更重要的是,您必须首先实现正确性。
递增
静态方法中存在一个错误:如果数组参数的大小不均匀,则为
右侧
子数组分配的大小不正确:
int[]right=new int[q];
应为

int[] right = new int[arr.length - q];
此外,如果数组太小,则不应尝试拆分该数组

关于优化,仅当子阵列大小低于阈值(介于16到128个元素之间)时,才应回退到
InsertionSort()
。使用不同阈值和各种分布进行仔细的基准测试将有助于确定系统的良好阈值

按照当前实现的方式,函数的时间复杂度为O(N2),因为除了最后一个合并阶段外,所有合并阶段都遵循
InsertionSort
。要将复杂度降低到O(N.log(N)),必须在子阵列上递归,直到其大小低于固定阈值

以下是修改后的版本:

package com.algorithms.sort;
公共类合并排序{
公共静态int阈值=32;
公共静态整数[]增加(整数[]arr){

如果(arr.length)这个问题有帮助吗?部分是的,但我们如何在不使用递归的情况下实现合并排序呢?根据您的链接,它说O(n lg n)是递归和非递归合并排序的时间复杂度。通过简单的谷歌搜索很容易得到。不是吗?我建议你搜索如何以非递归方式编写递归,反之亦然。这会给你一个想法。正如你所看到的,链表最适合排序。这是一个相当广泛的说法。如果你有一个数组如果要求对其进行排序,则创建一个链表是没有意义的。这将使内存为O(n)。此外,由于无法索引到链接列表中,因此必须对其进行迭代,以找到将其拆分为两个的中间点。这是额外的工作。跟随
next
指针所需的时间也比递增数组索引所需的时间要长。很可能链接列表排序的常数更高,并且比数组的速度慢排序时,在数据结构选择方面,ort听起来很有效。无论如何,为什么要选择链表而不是数组?在任何排序算法中是否存在链表优先于数组的用例?我不确定是否有。您看到了吗?