1. 程式人生 > >[資料結構]直接插入排序

[資料結構]直接插入排序

插入排序的思想

  插入排序是一種簡單隻管的排序方法,其基本思想在於每一次待排序的記錄,按其關鍵字大小插入到前面已經排好序的子序列中,直到全部記錄插入完成。
  假設在排序過程中,待排序表L[1….n]在某次排序過程中的某一時刻狀態如下:
  這裡寫圖片描述
  為了實現將元素L(i)插入到已經有序的子序列L[1…i-1]中,我們需要執行以下操作:
  1)查找出L(i)在L[1…i-1]中的插入位置k。
  2)將L[k…i-1]中所有元素全部後移一個位置。
  3)將L(i)複製到L(k)。
  為了實現對L[1…n]的排序,可以將L(2)~L(n)依次插入到前面已排好序的子序列中,初始假定L[1]是一個已經排好序的子序列。上述操作將執行n-1次就能得到一個有序的表。插入排序在實現上通常採用就地排序(空間複雜度為O(1)),因此在從後向前的比較過程中,需要反覆把已排序元素逐步往後挪位,為新元素提供插入空間。

程式碼分析

void  InsertSort(ElemType A[],int n){
    int i,j;
    for(i=2;i<=n;i++)//依次將A[2]到A[n]插入到前面已排序序列
        if(A[i].key<A[i-1].key){
        //如果A[i]的關鍵字小於其前驅,則需要將A[i]插入有序表
        A[0]=A[1];//複製為哨兵,A[0]不存放元素
        for(j=i-1;A[0].key<A[j].key;--j)//從後往前查詢待排序插入位置
            A[j+1]=A[j];//向後挪位
        A[j+1
]=A[0];//複製到插入位置 } }

演算法效能分析

空間複雜度:僅使用了常數個輔助單元,因而空間複雜度為O(1)。
時間複雜度:在排序過程中,向有序子表中逐個地插入元素的操作進行了n-1趟,每趟操作都分為比較關鍵字和移動元素,而比較次數和移動次數取決於待排序表的初始狀態。
  在最好的情況下,表種元素已經有序,此時插入每一個元素都只需要比較一次而不用移動元素,因而時間複雜度為O(n)。
  在最壞情況下,表中元素順序剛好和排序結果中元素順序相反(逆序)時,總的比較次數達到最大,為∑i,總的移動次數也達到最大,為∑i+1。
  平均情況下,考慮待排序表中的元素是隨機的,此時可以取上述最好和最壞情況的平均值作為平均情況下的時間複雜度,總的比較次數與總的移動次數均為約n²/2。
  由此,直接插入排序演算法的時間複雜度為O(n²),雖然這般插入排序演算法的時間複雜度也有O(n²),但對於資料量比較小的排序表,折半插入排序往往能表現出很好的效能。
  穩定性:由於每次插入元素時總是從後向前先比較再移動,所以不會出現相同元素相對位置發生變化的情況,即直接插入排序是一個穩定的排序方法。
  適用性:直接插入排序演算法適用於順序儲存和鏈式儲存的線性表。當為鏈式儲存時,可以從前往後查詢指定元素的位置。