插入排序演算法

2021-10-09 02:46:44 字數 3400 閱讀 4502

插入排序是一種簡單直觀的排序方法,其基本思想是每次將乙個待排序的記錄按其關鍵大小插入到前面已經排好序的子串行中,直到全部記錄插入完成。由插入排序的思想可以引申出三個重要的排序演算法:直接插入排序,折半插入排序和希爾排序。

在排序過程中,待排序表l[1...n]在某次排序過程中的狀態如下:

此時將元素l[i]插入到已經有序的子串行l[1...i-1]中,需要執行下列操作:

查詢出l[i]在l[1...i-1]中的插入位置k;

將l[k...i-1]中的所有元素都要依次往後移動乙個位置;

將l[i]插入位置k。                             

為了實習那l[1,n]的排序,可以將l(2)~l(n)依次插入到前面已經排好序的子串行中,初始值l[1]可以視為是乙個已經排好序的子串行。從而執行n-1此插入就能得到乙個有序的表。插入排序在實現上通常採用就地排序(空間複雜度o(1)),因此在從後向前的比較過程中,需要反覆吧已排序元素逐步向後挪位,為新元素提供插入空間。

直接插入排序演算法適用於順序儲存和鏈式儲存的線性表。為鏈式儲存時,可以從前往後查詢指定元素的位置。

排序過程**

順序儲存**實現

#includevoid insertsort(int a, int n)	}}

int main(); //b[0]為輔助記憶體空間

insertsort(b, 8);

for(int i = 1; i < 9; i++)

return 0;

}

結果展示:

從直接插入排序演算法可得,每趟插入的過程中都會進行兩項工作:

從前面的有序子表中查詢出待插入元素應該被插入的位置;

將待插入資料的位置的資料移出,並將待插入資料移入。

演算法效能分析演算法

最好時間

最壞時間

平均時間

額外空間/空間複雜度

穩定性直接插入排序

o(n)

o(n^2)

o(n^2)

1(常數)/o(1)

穩定由直接插入排序可知,總是一邊比較一邊移動元素,除此之外,我們可以折半查詢找出元素待插入的位置,然後統一地移動待插入位置之後的所有元素。

實際上,折半插入排序通過對有序序列部分進行折半查詢來減少比較的元素的次數,約為o(nlog2^n),該比較次數與待排序表的初始化狀態無關,進取決於表中的元素個數n;當時元素的移動次數並未改變,它依賴於待排序的初始狀態。因此,折半插入排序的時間複雜度仍為o(n^2),但對於資料量不很大的排序表,折半插入排序往往效能優越,所以折半插入排序是一種穩定的排序方法。因為基於陣列下標實現查詢排序所以折半插入排序適用於順序儲存結構。

**實現:

#includevoid halfinsertsort(int a, int n)

for(j = i - 1; j >= high + 1; --j)

a[j+1] = a[j]; //統一後移元素,空出插入位置

//a[high+1] = a[0];

a[j+1] = a[0];

} }}int main() ; //b[0]為輔助記憶體空間

halfinsertsort(b, 8);

for(int i = 1; i < 9; i++)

return 0;

}

結果展示:

演算法效能分析:演算法

最好時間

最壞時間

平均時間

額外空間/空間複雜度

穩定性折半插入排序

o(n)

o(n^2)

o(nlog2^n)

1(常數)/o(1)

穩定直接插入排序演算法的時間複雜度為o(n2),但若待排序的序列為「正序」時,其時間複雜度可以提高值o(n),由此可見,它更適合於基本有序的排序表和資料量不大的排序表。希爾排序正是基於這兩點對直接插入排序進行改進而得來,又稱縮小增量排序。

先將待排序表分割成若干個形如l[i,i + d,i + 2d,...,i + kd]的「特殊子表」,即把相隔某個"增量"的記錄組成乙個子表,對各個子表分別進行直接插入排序,當整個表中的元素已呈「基本有序」時,再對全體記錄進行一次直接插入排序。

希爾排序演算法僅適用於線性表為順序儲存的情況。

希爾排序的過程如下:

先取乙個小於n的步長d1,把表中的全部記錄分成d1組,所有距離為d1的倍數的記錄放在同一組,在各組內進行直接插入排序;

取第二個步長d2

如對於資料序列:49 38 65 97 76 13 27 49 55 04

**實現:

#includevoid shellsort(int a, int n) {

int d,i,j;

for(d = n/2; d >= 1; d = d/2) {

for(i = d+1; i <= n; i++ ) {

if(a[i] < a[i-d]) { //需將a[i]插入有序增量子表

a[0] = a[i]; //暫存a[0]

for(j = i-d; j>0 && a[0]結果展示:

演算法效能分析:演算法

最好時間

最壞時間

平均時間

額外空間/空間複雜度

穩定性希爾排序

o(n)

o(n^2)

o(n^1.3)

1(常數)/o(1)

不穩定空間效率:僅使用了常數個輔助單元,因而空間複雜度為o(1)。

時間效率:由於希爾排序的時間複雜度依賴於增增量序列的函式,這是個數學上尚未解決的難題,當n在某個特定的範圍時,希爾排序的時間複雜度約為o(n^1.3)。最壞的情況下希爾排序的時間複雜度為o(n^2)。

穩定性:當相同關鍵字被劃分到不同的子表中,會存在改變它們之間的相對次序,因此希爾排序十一總不穩定的排序。

適用性:希爾排序演算法僅適用於線性表為順序儲存的情況。

插入排序演算法

插入排序演算法 思想 把排序過程看作是序列單個有序擴充套件為整體有序的過程,即首先取序列第二個元素與第乙個元素比較,將其插入合適位置,再將第三個元素與前兩個元素比較,將其插入合適位置,如此進行,直到最後取第n個元素與前n 1個元素進行比較並將其插入合適位置。演算法 建立日期 2004 12 14 插...

演算法 插入排序

include include 插入排序 n 2為的效率。具體思想 將陣列分為兩部分,一部分是有序的,一部分為無序的 然後從無序中選取乙個數插入在有序的數中的恰當的位置,以此迭代,直到無序的數全部遍厲完畢 void insert sort int a,int n a j tmp break retu...

插入排序演算法

下面這段話摘自 一般來說,插入排序都採用in place在陣列上實現。具體演算法描述如下 從第乙個元素開始,該元素可以認為已經被排序 取出下乙個元素,在已經排序的元素序列中從後向前掃瞄 如果該元素 已排序 大於新元素,將該元素移到下一位置 重複步驟3,直到找到已排序的元素小於或者等於新元素的位置 將...