【问题标题】:Needed help understanding insertion sort需要帮助理解插入排序
【发布时间】:2010-01-28 21:23:31
【问题描述】:

在这段代码中这是如何工作的(java):

/** Move A[A.length-1] to the first position, k, in A such that there
* are no smaller elements after it, moving all elements
* A[k .. A.length-2] over to A[k+1 .. A.length-1]. */

static void moveOver (int A[]) {
   moveOver (A, A.length-1);
}

/** Move A[U] to the first position, k<=U, in A such that there
* are no smaller elements after it, moving all elements
* A[k .. U-1] over to A[k+1 .. U]. */

static void moveOver (int A[], int U) {
  if (U > 0) {
    if (A[U-1] > A[U]) {
      /* Swap A[U], A[U-1] */
     moveOver (A, U-1);
    }
  }
}

我是从伯克利的一门 CS 课上学到的,我正在网上学习,自学。这不是家庭作业(我希望是但不是那么幸运)。我不明白的是:

假设 A[] 中的数字是 8, 2, 10, 5, 4, 12。当我在上面使用它们时,我会在迭代中得到它,并跟踪它。

  1. 最高的下标是U,或者在 这种情况下 12,U-1 是 4,没有交换 完成
  2. U 现在是 4(递归 U-1),它上面的数字是 5(另一个 U-1)。他们被交换了。
  3. U 现在是 4,因为四个刚刚上移,而 10 是 U-1,它们被交换了。

我的序列现在是 8,2,4,10,5,12。

我的问题是如何获得我已经通过的数字?例如,如果我从不回到那个下标进行测试,我将如何获得五个。

我认为我没有正确跟踪程序并且我对递归感到困惑。为此,请假设交换已正确完成。

谢谢。

se

【问题讨论】:

    标签: recursion insertion-sort


    【解决方案1】:

    我认为你对问题的误解的关键实际上隐藏在你的问题标题中

    需要帮助理解插入排序

    该算法确实只对当前元素进行排序,但其想法是每次将元素添加到数组时都会运行它。这样,每次调用它时,数组的其余部分就已经有序了。换句话说,您只是想对最后一个元素进行排序。

    因此,使用您的示例数字(8、2、10、5、4、12)并按顺序将它们一次添加/排序到数组中,顺序如下(每一步的排序恰好发生你已经描述了):

    To be added         | old array      | after push     | Result (after moveOver())
    (8, 2, 10, 5, 4, 12)| []             | [8]            | [8]
    (2, 10, 5, 4, 12)   | [8]            | [8,2]          | [2,8]
    (10, 5, 4, 12)      | [2,8]          | [2,8,10]       | [2,8,10]
    (5, 4, 12)          | [2,8,10]       | [2,8,10,5]     | [2,5,8,10]
    (4, 12)             | [2,5,8,10]     | [2,5,8,10,4]   | [2,4,5,8,10]
    (12)                | [2,4,5,8,10]   | [2,4,5,8,10,12]| [2,4,5,8,10,12]
    

    【讨论】:

      【解决方案2】:

      关于您的跟踪:您在第 2 点出错了,因为 if 条件不成立,因此没有进行递归调用。

      如果递归让你感到困惑,重写为迭代形式可能会有所帮助:

      static void moveOver (int A[], int U) {
        while (U > 0 && A[U-1] > A[U]) {
          /* Swap A[U], A[U-1] */
          --U;
        }
      }
      

      现在很容易看出,只要遇到较小的元素,循环就会停止。要使这是一个完整的排序算法,还需要做更多的工作。无论哪种方式,这都不是插入排序;在我看来,它更像是部分冒泡排序。

      现在你说你是从哪里得到这个代码的?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多