需要帮助理解插入排序

时间:2010-01-28 21:23:32

标签: recursion insertion-sort

在这段代码中,这是如何工作的(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);
    }
  }
}

我从berkeley cs课上得到了这个,我正在上网,自学。这不是功课(我希望但不是那么幸运)。我不明白的是:

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

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

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

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

    谢谢。

    SE

2 个答案:

答案 0 :(得分: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]

答案 1 :(得分:0)

关于你的追踪:你在第2点出错了,因为if条件不成立,所以不会进行递归调用。

如果递归使您感到困惑,则可能有助于重写为迭代形式:

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

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

现在你说你从哪里获得这段代码?