排序 插入排序

2021-05-27 05:02:05 字數 3322 閱讀 4630

插入排序(insertion sort)的基本思想是:每次將乙個待排序的記錄,按其關鍵字大小插入到前面已經排好序的子檔案中的適當位置,直到全部記錄插入完成為止。

直接插入排序基本思想

1.直接插入排序的基本思想 

直接插入排序(straight insertion sorting)的基本思想是:把n個待排序的元素看成為乙個有序表和乙個無序表,開始時有序表中只包含乙個元素,無序表中包含有n-1個元素,排序過程中每次從無序表中取出第乙個元素,將它插入到有序表中的適當位置,使之成為新的有序表,重複n-1次可完成排序過程。

把a[i]插入到a[0],a[1],...,a[i-1]之中的具體實施過程為:先把a[i]賦值給變數t,然後將t依次與a[i-1],a[i-2],...進行比較,將比t大的元素右移乙個位置,直到發現某個j(0<=j<=i-1),使得a[j]<=t或j為(-1),把t賦值給a[j+1].

2、第i-1趟直接插入排序:

通常將乙個記錄r[i](i=2,3,…,n-1)插入到當前的有序區,使得插入後仍保證該區間裡的記錄是按關鍵字有序的操作稱第i-1趟直接插入排序。

排序過程的某一中間時刻,r被劃分成兩個子區間r[1..i-1](已排好序的有序區)和r[i..n](當前未排序的部分,可稱無序區)。

直接插入排序的基本操作是將當前無序區的第1個記錄r[i]插人到有序區r[1..i-1]中適當的位置上,使r[1..i]變為新的有序區。因為這種方法每次使有序區增加1個記錄,通常稱增量法。

插入排序與打撲克時整理手上的牌非常類似。摸來的第1張牌無須整理,此後每次從桌上的牌(無序區)中摸最上面的1張並插入左手的牌(有序區)中正確的位置上。為了找到這個正確的位置,須自左向右(或自右向左)將摸來的牌與左手中已有的牌逐一比較。

一趟直接插入排序方法

1.簡單方法

首先在當前有序區r[1..i-1]中查詢r[i]的正確插入位置k(1≤k≤i-1);然後將r[k..i-1]中的記錄均後移乙個位置,騰出k位置上的空間插入r[i]。

注意:若r[i]的關鍵字大於等於r[1..i-1]中所有記錄的關鍵字,則r[i]就是插入原位置。

2.改進的方法

一種查詢比較操作和記錄移動操作交替地進行的方法。

具體做法:

將待插入記錄r[i]的關鍵字從右向左依次與有序區中記錄r[j](j=i-1,i-2,…,1)的關鍵字進行比較:

① 若r[j]的關鍵字大於r[i]的關鍵字,則將r[j]後移乙個位置;

②若r[j]的關鍵字小於或等於r[i]的關鍵字,則查詢過程結束,j+1即為r[i]的插入位置。

關鍵字比r[i]的關鍵字大的記錄均已後移,所以j+1的位置已經騰空,只要將r[i]直接插入此位置即可完成一趟直接插入排序。

直接插入排序演算法

1.演算法描述

實現程式

void insert_sort(elemtype a,int n)

//待排序元素用乙個陣列a表示,陣列有n個元素

{ int i,j;

elemtype t; 

for ( i=1; i=0)&& (t(3)穩定性:

插入排序是穩定的,因為具有同一值的元素必然插在具有同一值得前乙個元素的後面,即相對次序不變.

(4)結構的複雜性及適用情況

插入排序是一種簡單的排序方法,他不僅適用於順序儲存結構(陣列),而且適用於鏈結儲存結構,不過在鏈結儲存結構上進行直接插入排序時,不用移動元素的位置,而是修改相應的指標。

2.哨兵的作用

演算法中引進的附加記錄r[0]稱監視哨或哨兵(sentinel)。

哨兵有兩個作用:

① 進人查詢(插入位置)迴圈之前,它儲存了r[i]的副本,使不致於因記錄後移而丟失r[i]的內容;

② 它的主要作用是:在查詢迴圈中"監視"下標變數j是否越界。一旦越界(即j=0),因為r[0].key和自己比較,迴圈判定條件不成立使得查詢迴圈結束,從而避免了在該迴圈內的每一次均要檢測j是否越界(即省略了迴圈判定條件"j>=1")。

注意:① 實際上,一切為簡化邊界條件而引入的附加結點(元素)均可稱為哨兵。

【例】單鏈表中的頭結點實際上是乙個哨兵

② 引入哨兵後使得測試查詢迴圈條件的時間大約減少了一半,所以對於記錄數較大的檔案節約的時間就相當可觀。對於類似於排序這樣使用頻率非常高的演算法,要盡可能地減少其執行時間。所以不能把上述演算法中的哨兵視為雕蟲小技,而應該深刻理解並掌握這種技巧。

給定輸入例項的排序過程

設待排序的檔案有8個記錄,其關鍵字分別為:49,38,65,97,76,13,27,49。為了區別兩個相同的關鍵字49,後乙個49的下方加了一下劃線以示區別。其排序過程見【動畫模擬演示】

演算法分析

1.演算法的時間效能分析

對於具有n個記錄的檔案,要進行n-1趟排序。

各種狀態下的時間複雜度:

┌─────────┬─────┬──────┬──────┐

│ 初始檔案狀態     │   正序   │     反序   │無序(平均)  │

├─────────┼─────┼──────┼──────┤

│ 第i趟的關鍵      │   1      │     i+1    │ (i-2)/2  │

│ 字比較次數       │          │            │            │

├─────────┼─────┼──────┼──────┤

│總關鍵字比較次數  │   n-1    │(n+2)(n-1)/2│ ≈n2/4     │

├─────────┼─────┼──────┼──────┤

│第i趟記錄移動次數 │   0      │ i+2        │ (i-2)/2  │

├─────────┼─────┼──────┼──────┤

│總的記錄移動次數  │   0      │(n-1)(n+4)/2│ ≈n2/4     │

├─────────┼─────┼──────┼──────┤

│時間複雜度        │  0(n)  │ o(n2)    │ o(n2)    │

└─────────┴─────┴──────┴──────┘

注意:初始檔案按關鍵字遞增有序,簡稱"正序"。

初始檔案按關鍵字遞減有序,簡稱"反序"。 

2.演算法的空間複雜度分析

演算法所需的輔助空間是乙個監視哨,輔助空間複雜度s(n)=o(1)。是乙個就地排序。

3.直接插入排序的穩定性

直接插入排序是穩定的排序方法。

插入排序 折半插入排序

折半插入排序 binary insertion sort 直接插入排序採用順序查詢法查詢當前記錄在已排好序的序列中插入位置,這個 查詢 操作可利用 折半查詢 來實 現,由此進行的插入排序稱之為折半插入排序 binary insertion sort 演算法思想 1 將待排序的記錄存放在陣列r 1.n...

插入排序 折半插入排序

折半插入排序是基於直接插入排序的優化。直接插入排序 將第i個元素插入時,通過折半查詢的方式,來查詢第i個元素合適的位置。當0 i 1 位置上的元素都已經排序ok,現需要插入第i個元素,設其值為temp 令low 0,high i,mid high low 2。那麼temp可能插入的位置是 low h...

插入排序 希爾插入排序

本文借鑑於lsgo實驗室創始人馬老師 演算法 希爾插入排序 delta len nums 2 while delta 0 shell delta,nums delta delta 2return nums defshell delta,key for i in range delta,len key...