插入排序

    插入排序也是簡單排序。
(1)算法思想
逐個處理每個待排序的記錄,將每個待處理記錄與前面已經排好序的記錄進行比較,然後插入到適當的位置。
(2-1)算法描述(僞代碼),以升序爲例:
InsertSort(int a[], int n)
{
        for (int i=1; i<n; i++)
        {
                for (int j=i; j>0; j--)
                {
                     if (a[j]<a[j-1])
                     {    tmp = a[j];
                            a[j] = a[j-1];
                            a[j-1] = tmp;
                     }
                     else
                         break;
                }
        }
}
 
(2-2)算法分析:
1)穩定
2)空間代價:Θ(1)     (swap時需要的輔助空間)
3)時間代價:
最佳情況:n-1次比較,0次交換,Θ(n)。
最差情況:比較和交換次數都爲:從1到n-1求和,Σi=n(n-1)/2, Θ(n^2)。
平均情況:n(n-1)/4 (n個數,每兩個一組,或稱爲一對,共有n(n-1)/2組,這些組每組是逆序的概率是1/2), Θ(n^2)。
(3-1)可能的優化。
插入過程中,減少交換次數,用“移動前面元素的位置”來代替交換。僞代碼:
Improved_InsertSort(int a[], int n)
{
        for (int i=1; i<n; i++)
        {
                key = a[i];
                j = i-1;
                while (j>=0 && a[j]>key)
                {
                     a[j+1] = a[j];
                     j--;
                }
                a[j+1] = key;
        }
}
 
(3-2)算法分析:
總體上複雜度還是Θ(n^2)。但是當n很大時交換次數將明顯減少,例如在最差情況下,插入元素a[m]時,沒有優化的算法由於交換將產生3m次賦值,優化後的算法,需要m+2次賦值,當m很大時,顯然3m>>m+2。
 
(4-1) 監視哨優化。
對於特殊的數組定義,如待排序元素存儲在a[1] ~ a[n],a[0]不保存待排序元素,則a[0]可以用來做監視哨,從而可以省略上面代碼中while循環對數組越界的判斷。
Surveillant_InsertSort(int a[], int n)    
{    
                for (int i=2; i<=n; i++)    
                {    
                                a[0] = a[i];    
                                j = i-1;    
                                while (a[j]>a[0])    
                                {    
                                         a[j+1] = a[j];    
                                         j--;    
                                }    
                                a[j+1] = a[0];    
                }    
}
 
(4-2)分析。
優化非常有限。如果源數組不是按照上述定義,還要轉換,則失去了優化的意義。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章