1. 程式人生 > >插入排序演算法詳解(C++實現)

插入排序演算法詳解(C++實現)

插入排序

輸入:n個數(a1,a2,...,an)。

輸出:輸入序列的一個排列(a1',a2',...,an'),使得a1'到an'為有序序列。

待排序的數稱為關鍵字key。

插入排序與平時生活中打牌時,整理手中牌的順序相似。最開始手中沒有牌,我們從桌上摸起一張牌,將它插入正確的位置,在插入時,我們需要依次進行比較;任何時候,我們手中的牌都是已經排好序的,並且這些牌都是桌上那副牌最頂上的一張。

插入排序偽程式碼表示:

Insertion-sort(A)

//引數A是待排序陣列

         forj ← 2 to length[A]

                   dokey ← A[j]

                            ▷  insert A[j] into the sorted sequence A[1…j-1]

                            //將A[j]插入已排好序的A[1…j-1]中

                            i← j-1

                            whileI > 0 and A[j] > key

                                     doA[i+1] ← A[i]

                                               I← i-1

                            A[i+1]← key

迴圈不變式與插入演算法的正確性:

在外層for迴圈(迴圈變數為j)的每一輪迭代開始,包含元素A[1…j-1]的子陣列構成已排好序的陣列。元素A[j+1…n]對應未排序的子陣列。實際上,已排好序的A[1…j-1]就是原陣列A[1…n]的前j-1個元素,只不過已經排好序了。

迴圈不變式的證明:

初始化:循第一輪開始時,j=2,此時子陣列只包含一個元素A[1],並且這個子陣列是已經排好序的,因此迴圈第一輪開始是正確的。

能否保持:在外層for迴圈中,要將A[j-1]、A[j-2]、A[j-3]等元素向右移動一個位置,直到找到A[j]的適當位置為止,此時將A[j]插入。(類似歸納法)因此如果迴圈的迭代開始之前它是正確的,那麼在下一次迭代開始之前,它也能保持正確。

終止:對於插入排序來說,當j大於n時,也就是j=n+1,外層for迴圈結束,外層for迴圈結束。在迴圈不變式中,將j替換為n+1,即有子陣列A[1…n]包含了原先的A[1…n]中的元素,但是現在已經排好了序。因此整個陣列就排好了序,演算法正確。

複雜度及穩定性:

最壞時間複雜度:O(n^2)

最優時間複雜度:O(n)

平均時間複雜度:O(n^2)

排序演算法穩定性:穩定

空間複雜度:O(1)

插入排序的C++語言實現:

void insertion_sort(int *A,int len)

{

         for(int j=1; j<len; j++) 

   { 

       int key = A[j]; 

       int i = j-1; 

       while (i>=0 && A[i]>key) 

       { 

           A[i+1] = A[i]; 

           i--; 

       } 

       A[i+1] = key; 

    }

}