【问题标题】:Understanding Recursion with Merge sort使用归并排序理解递归
【发布时间】:2017-02-27 11:15:03
【问题描述】:

我看到一些帖子了解归并排序。我知道递归方法维护堆栈来保存值。 (我的理解是 return 语句结果将在堆栈中)

private int recur(int count) {
    if (count > 0) {
        System.out.println(count);
        return count + recur(--count); // this value will be in stack.
    }
    return count;
}

我对合并排序感到困惑,这里的堆栈是如何维护的。

private void divide(int low, int high) { 
    System.out.println("Divide => Low: "+ low +" High: "+ high);
    if (low < high) {
        int middle = (low + high) / 2; 
        divide(low, middle); // {0,7},{0,3}, {0,1} ;
        divide(middle + 1, high); // {0,0};  high = 1; // 2nd divide
        combine(low, middle, high);
    }
}
  1. 所有局部变量都使用堆栈吗?
  2. 当第二个递归方法调用时,第一个递归也会加入吗? 在这种情况下如何维护堆栈?

【问题讨论】:

  • This 解释得最好。
  • 对于更简单的问题,您会更容易理解递归。在此之前,您应该了解堆栈是什么,函数是如何被调用的,什么值被压入堆栈,返回值如何传播给调用者以及参数是如何传递给函数的。

标签: recursion mergesort


【解决方案1】:

您只需要知道语句需要完成并返回,并且您从divide 调用dividecombine 的工作方式相同。两者都需要在下一行代码执行之前完成,或者,如果没有更多行,则函数返回。是的,它是用堆栈完成的,但它真的不重要。

  1. waiters 变量lowhighmiddle 的状态只是当前调用绑定,因此它们不会与其他调用混合。

  2. 每次嵌套新调用时,它都会获得自己的变量,并且每个都需要完成。当 low-middle 完成时,它会调用 middle+1-high 并在完成时合并。这些调用会做同样的事情,所以你会有更深的嵌套,调用结构的访问方式就像一个二叉树结构,叶子是low == high(一个元素)。

忠告。在查看递归代码时,请尝试从叶子到更复杂的树。例如。首先尝试使用基本情况,然后是最简单的默认情况。例如。

  1. 1 个元素数组:什么都不做
  2. 2 元素数组:-> 1 元素数组(见 1.),1 元素数组,组合
  3. 4 元素数组:-> 2 元素数组(见 2.),2 元素数组,组合

请注意,2. 你知道两个递归调用都不会做任何事情,combine 可能会做一个交换。 3. 在combine 之前执行 2. 两次(包括交换),这将合并 2 个已排序的 2 元素数组。您可能正在以另一种方式看待它,这需要您停止 3. 执行 2. 停止它并执行 1.,然后下一个 1,然后返回 2. 执行有两个 1 的文本......它需要笔和纸。使用到目前为止所学的知识从叶到根查看它可以让您更容易理解它。我确实认为函数递归比像合并排序这样的变异结构更容易掌握。例如。斐波那契数列。

【讨论】:

    猜你喜欢
    • 2013-10-05
    • 1970-01-01
    • 2014-08-12
    • 2021-06-22
    • 1970-01-01
    • 2016-04-14
    • 2015-06-17
    • 2010-12-08
    • 2017-12-22
    相关资源
    最近更新 更多