1. 程式人生 > >插入排序Insertion-Sort

插入排序Insertion-Sort

最近在學習演算法導論這本書,對一些演算法進行了進一步的學習,在這裡記錄一下。

排序演算法可以分為兩種:內排序和外排序。在排序過程中,全部記錄存放在記憶體,則稱為內排序,如果排序過程中需要使用外存,則稱為外排序。內部排序是排序的基礎,在內部排序中,根據排序過程中所依據的原則可以將它們分為5類:插入排序(直接插入排序、二分法插入排序、希爾排序)、交換排序(氣泡排序、快速排序)、選擇排序(直接選擇排序、堆排序)、歸併排序和基數排序;根據排序過程的時間複雜度來分,可以分為三類:簡單排序、先進排序、基數排序。

首先,研究一下直接插入排序演算法(Insertion Sort),對於少量元素的排序,這是一個有效的演算法。演算法導論中提出了一個撲克牌的例子來形容插入排序,我們對撲克牌進行排序。開始時,左手為空且桌子上牌面向下,然後我們每次從桌子上拿走一張牌並將它插入左手中正確的位置。為了找到一張牌的正確位置,我們從右向左將它與手中已有的每張牌進行比較。

插入排序的偽程式碼表示如下,這裡定義陣列A[0,...,n-1]包含了一個長度為n的陣列,在虛擬碼中陣列長度n用A.length表示。

Insertion-Sort(A)
for j=1 to A.length-1
    key=A[j]
    //INSERT A[j] into the sorted sequence A[0...j-1]
    i=j-1
    while i>=0 and A[i]>key
        A[i+1]=A[i]
        i=i-1
    A[i+1]=key

插入排序的具體工作流程如下:(以下圖片來自演算法導論) 

具體實現的程式碼稍後補上,現在分析一下該演算法的時間複雜度:

當問題規模為n時,最好情況(序列本身有序):比較次數:n-1;移動次數:0
                              最差情況(逆序):比較次數:2+3+4+……+n=(n+2)n/2;
                                                              移動次數:Mmax=1+2+3+……+n-1=n*n/2
若待排序物件序列中出現各種可能排列的概率相同,則可取上述最好情況和最壞情況的平均情況。在平均情況下的關鍵字比較次數和物件移動次數約為 n^2/4。因此,直接插入排序的時間複雜度為 O(n^2)是一種穩定的排序方法。(若在待排序的記錄中,存在兩個或兩個以上的關鍵碼值相等的記錄,經排序後這些記錄的相對次序仍然保持不變,則稱相應的排序方法是穩定的方法,否則是不穩定的方法。)

空間複雜度為O(1),不需要額外儲存空間。