我理解递归的重点以及它在非常简单的情况下是如何工作的,E.G
// Make a func that that will add factorials
public long fact(long n){
if(n <= 1)
return 1;
else
return n * func(n-1)
}
我可以看到n
随着每次调用而减少,如果n = 5
输出将为120.在这种情况下,我理解递归是如何工作的。
然而,当它接到一些更复杂的电话时,我无法真正看到幕后发生的事情。我通常可以理解代码,但无法解释某人为什么或如何发生。 E.G
public void mergeSort(int[] list, int lowIndex, int highIndex){
if(lowIndex == highIndex)
return;
else{
int midIndex = (lowIndex + highIndex) / 2;
mergeSort(list, lowIndex, midIndex);
mergeSort(list, midIndex+1, highIndex);
merge(list, lowIndex, midIndex, highIndex);
}
}
我无法弄清楚这个递归mergeSort
调用如何返回它们返回的内容。
如果我们假设lowIndex = 0 & midIndex = 5
,这种方法有什么作用?
如果某人有其他一些例子可以在这个学习过程中给出好的提示,那么这也很有效:)
答案 0 :(得分:1)
我假设你知道合并逻辑是如何工作的
当你第一次调用mergeSort(lowIndex,midIndex)时,它会自动回忆很多次,直到它与长度为2的子阵列一起工作,易于订购(它们只需要比较)。
此时mergesort(0,1)已经完成,现在是时候执行mergesort(2,3),它将返回另一个长度为2的有序子数组;然后现在在合并函数中对这些子数组进行比较和合并。
所以该方法结束从它被调用的地方返回(在本例中是mergesort(0,3)),因此下一个要执行的语句是mergesort(4,7)。
考虑N无序数组的长度,重复该过程直到你回到顶部调用,其中合并了两个长度为N / 2(或N / 2和N / 2 -1,如果N为奇数)的子阵列。 / p>
答案 1 :(得分:0)
此方法不返回任何内容。相反,它管理逻辑的分而治之的部分,并调用merge()
,它执行(子)数组的就地排序,变异。
答案 2 :(得分:0)
Merge Sort是一种分而治之的算法,它将整个数组分成两半然后继续分割,除非有一个仅包含两个元素的子数组。然后算法继续并合并包含一个元素的子数组。排序他们。 然而,合并排序的递归调用堆栈在第一次运行时有点难以理解。
让我们说,我们有一个数组4,0,6,1,5,2,3
现在按照上面的代码,
Midindex = 3
第一次合并排序递归调用
(list,0,3) 当这返回时,因为它是递归并且满足基本情况,0 <3,
我们有, midindex = 1 所以下一个电话是 (列表,0,1)再次,当递归地调用它时,因为0 <1, 我们有midindex = 0
所以下一个电话是(list,0,0) 此调用未通过基本情况,
所以我们转到代码中的下一行 (列表,中+ 1,高) 这个调用解释为(list,1,1)[因为,按照上面的流程,mid是0] 再次列表,1,1基本情况失败, 所以我们向下移动下面的代码 合并(列表,低,中,高) 在这种情况下,这是 (列表,0,0,1)
因此合并后的子阵列将为0.4。
在此之后,控制返回到完成0,3的右侧合并 Midindex = 1 因此合并排序(列表,中间+ 1,高)[因为合并排序(列表,低,中)已经在上面完成)。 这进一步归结为,mergesort(list,2,3) 再次调用递归基本情况,因为2 <3 mid = 2 所以,合并sort(list,2,2)和类似的mergesort(list,3,3)。这两个调用都将失败基本情况,并将调用merge函数。 这样重复递归栈,最终结果是一个漂亮的排序数组。 我希望我很清楚。