插入排序算法就地和循环变体

时间:2015-04-20 10:48:23

标签: quicksort insertion-sort loop-invariant

第1部分
我知道QuickSort可以在原地使用'但是有人可以向我解释插入排序算法如何使用'到位'。

根据我的理解:

插入排序从第一个值开始,并将其与下一个值进行比较,如果该值小于我们切换位置的值。我们递归地继续这个。 (简短说明)

所以你会说这就是'到位'因为我们不创建一个新的数组来做这个,但只是比较一个数组中的两个元素?

如果我的理解错了,有人可以解释一下 用于插入排序的算法。

第2部分
另外,我如何使用插入排序来说明循环不变的想法?

我知道循环不变量是一个在循环的每次迭代之前和之后立即生效的条件,但是我不确定这与插入排序有什么关系。

1 个答案:

答案 0 :(得分:0)

与评论部分中提到的Thorsten一样,您已经描述了冒泡排序。从Wikipedia修改,冒泡排序的伪代码如下:

procedure bubbleSort( A : list of sortable items )
   n = length(A)
   for i = 1 to n inclusive do // Outer Loop
     for j = 1 to n-1-i inclusive do
       /* if this pair is out of order */
       if A[j] > A[j+1] then
         swap(A[j], A[j+1])
       end if
     end for
   end for
end procedure

冒泡排序中的循环不变量(对于外循环)将是在循环的每次迭代之后整个数组,直到当前值i将被排序。这是因为,每次到达外循环时,它将经过内循环的所有迭代(从i到n-1),在那里找到最小元素并用第i个交换该元素。

实际上,冒泡排序已到位,因为所有排序都发生在原始数组本身内,并且不需要单独的外部数组。

编辑 - 现在插入排序:

伪代码如下(所有冰雹Wikipedia):

 for i = 1 to length(A) - 1
    x = A[i]
    j = i
    while j > 0 and A[j-1] > x
        A[j] = A[j-1]
        j = j - 1
    end while
    A[j] = x[3]
 end for

这里,在每一步中,会发生的情况是,对于每个元素,您选择将其插入到数组中的适当位置,即,将其插入到比数组中小的第一个元素之后。更详细一点,内部循环的作用是,它将元素向右移动,直到遇到比所考虑的元素小的元素,此时您将元素插入到较小的元素之后。这将意味着直到上述元素的每个元素都被排序。外部循环确保对数组中的所有元素执行此操作,这意味着在外部循环完成时,对数组进行排序。

外部循环的循环不变量与之前一样,在第i次迭代之后,直到当前i的所有元素将被排序。然而,在ith交互之前,所有直到i-1的元素都将被排序。

插入排序算法不需要外部数组进行排序。更具体地说,所有操作都是在数组本身上完成的(除了我们需要存储我们当前试图插入到其适当位置的元素的一个变量),并且没有使用外部数组 - 没有从该数组复制例如,另一个。因此,算法所需的空间复杂度(当然,不包括数组本身占用的空间)将为O(1),而不是依赖于数组的大小,而排序就位,就像冒泡一样。