方法结束前的递归不是无限循环?

时间:2014-03-23 23:40:42

标签: java recursion

我理解尾递归,因为它的函数类似于迭代,在方法调用自身的末尾使用新参数。但是当在循环结束时在代码之前放置递归调用时,为什么它不能无限地调用它?在下面的代码中,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);
  }
}

3 个答案:

答案 0 :(得分:1)

有些right > left为假的基本情况。然后,该函数一次调用自身,因此它成功返回。

答案 1 :(得分:1)

好吧,最终你会在leftright相等的情况下调用它,因此不会输入if块,并且递归结束。

例如,如果您使用left = 0, right = 4进行调用,则下一个电话会有left = 0, right = 2,然后是left = 0, right = 1,最后是left = 0, right = 0。这最后一个电话不会进一步递归。

要证明递归结束,请考虑leftright之间的差距。这会减少每次,因此它必须最终达到0.第一次调用会减少,因为mid保证为< right,并且第二次调用会减少,因为mid + 1可以保证是> left

答案 2 :(得分:1)

注意

if (right > left)

这可以防止在right <= left(实际上right永远不会小于left时继续递归,因此在right == left时停止递归。它有点像for循环中的i > 0