1. 程式人生 > >To be a Better man

To be a Better man

插入的基本思想

①每次插入,都從前面的有序子表中查找出待插入元素應該被插入的位置;   ②給插入位置騰出空間,將待插入元素複製到表中的插入位置。   注意到該演算法中,總是邊比較邊移動元素,下面將比較和移動操作分離開來,即先折半查找出元素的待插入位置,然後再同意地移動待插入位置之後的所有元素。當排序表為順序儲存的線性表時,可以對直接插入排序演算法作如下改進:由於是順序儲存的線性表,所以查詢有序子表時可以用折半查詢來實現。在確定出待插入位置後,就可以同意地向後移動元素了。

演算法程式碼

void InsertSort(Elemtype A[],int n){ int i,j,low,high,mid; for(i=2;i<=n;i++){ A[0]=A[i]; low=1; high=i-1;//設定折半查詢的範圍,從1到i-1,A[0]用來暫存元素 while(low<=high){ mid=(low+high)/2; if(A[mid].key>A[0].key) high=mid-1;//查詢左半子表 else low=mid+1;//查詢右半子表 }

    for(j=i-1;j>=high+1;--j)
            A[j+1]=A[j];//統一向後移動元素,空出插入位置
    A[high+1]=A[0];//插入操作
}

}1234567891011121314151617

例項及解析

第一趟:按上述程式碼的流程分析,從A[2]開始計算,{11}是一個已排序子表,按關鍵字13進行折半查詢它的位置,程式碼的上半部分查詢該元素元素應該插入的位置為A[2],所以下半部分並不需要移動元素,已排序子表為{11,13}   第二趟:從A[3]開始計算,low=1,high=2,mid=1,因為7<11,所以high=2-1=1;第二次迴圈mid=1,7<11,high=0,迴圈不滿足條件,此時開始移動元素;要移動的元素範圍為A[1]到A[2],A[1]=7。   第三趟第四趟依此類推……(只要記住一點,先折半查詢元素的應該插入的位置,然後統一移動應該移動的元素,再將這個元素插入到正確的位置)

演算法時間複雜度

時間複雜度:不難看出,折半插入排序僅僅是減少了比較元素的次數,約為O(nlogn),而且該比較次數與待排序表的初始狀態無關,僅取決於表中的元素個數n;而元素的移動次數沒有改變,它依賴於待排序表的初始狀態。因此,折半插入排序的時間複雜度仍然為O(n²),但它的效果還是比直接插入排序要好。   空間複雜度:很顯然,排序只需要一個位置來暫存元素,因此空間複雜度為O(1)。