我理解尾递归,因为它的函数类似于迭代,在方法调用自身的末尾使用新参数。但是当在循环结束时在代码之前放置递归调用时,为什么它不能无限地调用它?在下面的代码中,MergeSort_Recursive()在同一个方法中调用自身两次。如何才能达到对方法的第二次调用?当第一次调用该方法时,它将比较正确>离开然后初始化mid。然后它调用自己,然后我们转到方法的顶部,这将做正确的>再次进行比较,再次初始化mid,然后再次调用自身并不断重复此步骤。我当然知道这不是它的工作原理,否则这种方法会失败。所以我的问题是这是如何工作的,以及两种方法最终如何被调用?
static public void MergeSort_Recursive(int [] numbers, int left, int right)
{
int mid;
if (right > left)
{
mid = (right + left) / 2;
MergeSort_Recursive(numbers, left, mid);
MergeSort_Recursive(numbers, (mid + 1), right);
DoMerge(numbers, left, (mid+1), right);
}
}
答案 0 :(得分:1)
有些right > left
为假的基本情况。然后,该函数不一次调用自身,因此它成功返回。
答案 1 :(得分:1)
好吧,最终你会在left
和right
相等的情况下调用它,因此不会输入if
块,并且递归结束。
例如,如果您使用left = 0, right = 4
进行调用,则下一个电话会有left = 0, right = 2
,然后是left = 0, right = 1
,最后是left = 0, right = 0
。这最后一个电话不会进一步递归。
要证明递归结束,请考虑left
和right
之间的差距。这会减少每次,因此它必须最终达到0.第一次调用会减少,因为mid
保证为< right
,并且第二次调用会减少,因为mid + 1
可以保证是> left
。
答案 2 :(得分:1)
注意
if (right > left)
这可以防止在right <= left
(实际上right
永远不会小于left
时继续递归,因此在right == left
时停止递归。它有点像for循环中的i > 0
。