詳談內部排序之各種插入排序

2021-10-07 17:33:14 字數 3164 閱讀 7900

如上圖的插入撲克牌就是生活中最常見的插入排序。

直接插入排列過程:

先將序列中第 1 個記錄看成是乙個有序子串行,

然後從第 2 個記錄開始,逐個進行插入,直至整個序列有序。

例題:

為直接插入排序的詳細過程,其中有一些注意事項:

1)資料中有兩個49,其中乙個加粗,用來判斷這兩個49的前後順序是否發生變化,然後得到該排序是否穩定

2)從初始狀態開始只要i++,就會向後讀乙個資料,與前面的資料進行迴圈比較,然後插入到正確的位置,直到整個序列有序。

3)r0的作用是:儲存需要進行插入操作的資料,稱為監視號。

關鍵**:

void insertsort ( sqlist &l )  

} // insertsort

直接插入排序的效能分析:

綜上,由於待排記錄序列是隨機的,取上述二值的平均值。所以直接插入排序的時間複雜度為o(n^2)。

同時,直接插入排序是「穩定的」:關鍵碼相同的兩個記錄,在整個排序過程中,不會通過比較而相互交換。

​ 如上為直接插入排序的大致內容,但是對於這個操作,我們可以考慮到 l.r[1,…,i-1] 是按關鍵字有序的有序序列,則可以利用折半查詢實現「l.r[1,…,i-1]中查詢 l.r[i] 的插入位置」 。

所以對於如此實現的插入排序,我們稱之為為折半插入排序。

折半插入排序過程:

​ 折半插入排序在尋找插入位置時,不是逐個比較而是利用折半查詢的原理尋找插入位置。待排序元素越多,改進效果越明顯。

**例題:**有6個資料記錄,前5個已排序的基礎上,對第6個記錄排序。

如圖前五個是已經排列好的5個資料。

1)將已排列好的5個資料中 low = 15 , mid = 36, high = 69

2)判斷需要排列的數42mid的關係,例題中是大於關係 ,所以改變low和mid的值即:low = 53,mid =53

3)再次判斷,得到小於關係,所以改變low和high的值: high = 36 , low = 53

4)得到high注意:

1)mid,low,high ,這三個變數記錄的是資料在陣列中的下標,不是資料本身的值。

2)在進行折半的時候,大於關係,就將low的值變成mid+1,即:low = mid+1

​ 小於關係,就將high的值變成mid-1,即:high = mid-1

關鍵**:

void binsertsort ( sqlist &l)  // 插入點在高半區

for( j=i-1; j>=low; - -j ) l.r[j+1]=l.r[j]; // 記錄後移

l.r[low]=l.r[0]; } // 插入

}// binsertsort

折半插入排序的效能分析:

對於插入排序還有:2-路插入排序,表插入排序等。

下面只給出這兩個排序的基本思路,大家感興趣的話可以自己進行嘗試實現

(1) 基本思想:

​ 2-路插入排序是在折半插入排序的基礎上改進的,目的是減少排序過程中移動記錄的次數,但為此需要n個記錄的輔助空間。

(2) 具體做法:

​ 另設乙個和 l.r 同型別的陣列d,首先將 l.r[1] 賦值給d[1] ,並將d[1]看成是在排好序的序列中處於中間位置的記錄,然後從 l.r中第 2 個記錄起依次插入到d[1]之前或之後的有序序列中。先將待插入記錄的關鍵字和d[1] 的關鍵字進行比較。

若 l.r[i]

折半插入排序的效能分析:

​ 2-路插入排序只能減少移動記錄的次數,而不能絕對避免移動記錄。 2-路插入排序中,移動記錄的次數約為n^2/8。

​ 當l.r[1]是待排序記錄中關鍵字最小或最大的記錄時,2-路插入排序就完全失去了它的優越性。

(1) 基本思想

​ 通過改變排序過程中採用的儲存結構,減少在排序過程中進行「移動」記錄的操作。利用靜態鍊錶進行排序,並在排序完成之後,一次性地調整各個記錄相互之間的位置,即將每個記錄都調整到它們所應該在的位置上。

(2) 具體做法

​ 首先將靜態鍊錶中陣列下標為「1」的分量(結點)和表頭結點構成乙個迴圈鍊錶,然後依次將下標為「2」至「n」的分量(結點)按記錄關鍵字非遞減有序插入到迴圈鍊錶中。

表插入排序效能分析 :

​ 從表插入排序的過程可見,表插入排序的基本操作仍是將乙個記錄插入到已排好序的有序表當中。和直接插排序相比,不同之處僅是以修改2n次指標值代替移動記錄,排序過程中所需進行的關鍵字間的比較次數相同。因此表插入排序的時間複雜度仍是o(n2)。

​ 表插入排序的結果只是求得乙個有序鍊錶,則只能對它進行順序查詢,不能進行隨機查詢,為了能實現有序表的折半查詢,尚需對記錄進行重新排列。

1.我們都能理解,優秀排序演算法的首要條件就是

2.於是人們想了許許多多的排序辦法,目的就是為了提高排序的速度。

3.而在很長的時間裡,眾人發現儘管各種排序演算法花樣繁多,但時間複雜度都是o(n^2),似乎沒法超越了。

4.計算機學術界充斥著「排序演算法不可能突破o(n^2)」的聲音?

​ 終於有一天,當一位科學家發布超越了o(n^2) 新排序演算法後,緊接著就出現了好幾種可以超越o(n^2) 的排序演算法,並把內排序演算法的時間複雜度提公升到了o(nlog2n)。「不可能超越o(n^2) 」徹底成為了歷史。

之後我們會詳細講解,比插入排序更快的希爾排序

總結:​ 大家需要自己動手實現這些排序(尤其是前兩個排序方法),可以更加熟練的使用這些方法。

​ 對於上面有問題的地方大家可以提出來,我們可以一起討論,我會積極改正。

​ 希望本片文章對你有用,謝謝!

內部排序之插入排序

1.插入排序 插入排序可以視為兩步操作,一步是插入,一步是排序。插入排序的基本思想是將一條記錄插入到已經有序的序列中,繼而得到乙個有序的,資料個數加一的新序列。2.直接插入排序 直接插入排序把待排序序列視為兩部分 一部分是有序序列,通常在排序開始之時將序列中的第乙個資料視為有序序列 另一部分為待排序...

內部排序之插入排序 希爾排序

插入排序 insertion sort 插入排序由n 1趟 pass 排序組成,對於p 1趟到p n 1趟,插入排序可以保證從位置零到位置p上的元素全部有序,有這樣乙個事實 1 當插入p位置 設為data 的時候,從0位置到p 1已全部有序,如果data比p 1位置上的元素大,那麼直接放在p位置即可...

詳談內部排序之快速排序

交換排序 兩兩比較待排序記錄的關鍵碼,如果發生逆序 即排列順序與排序後的次序正好相反 則交換之,直到所有記錄都排好序為止 交換排序的主要演算法有 1 氣泡排序 2 快速排序 快速排序基本思想 1 基本思想 通過一趟排序將待排序列以樞軸為標準劃分成兩部分,使其中一部分記錄的關鍵字均比另一部分小,再分別...