插入排序的基本思想是: 將記錄分為有序和無序兩個序列。從無序序列中任取乙個記錄,然後根據該記錄的關鍵字大小在有序序列中查詢乙個合適的位置,使得該記錄放入這個位置後,這個有序序列仍然有序。每插入乙個記錄就稱為一趟插入排序,經過多趟插入排序,使得無序序列中的記錄全部插入到有序序列中,則排序完成。
直接插入排序:
void insert_sort(recordtype r,int n)
r[j+1] = temp; //比它大的元素向後移動之後,就可以插入了}}
插入第 i 個值r[i]時,r[0]、r[1]、…、r[i-1]已經有序。這時將待插入的r[i]關鍵字與已經有序的序列從後向前依次比較,好像有點繞口,其實就是r[i]之前的已經有序,而r[i]之後的無序,r[i]與r[i]之前的r[i-1]、r[i-2]、…、r[0],依次比較找到插入位置,並有後向前順序移動乙個位置,給待插入記錄讓位置。然後將r[i]放入剛才讓出的位置。這種插入使得前 i 個位置上的所有記錄r[0]、r[2]、…r[i]保持有序。
直接插入排序的過程如下圖:
a[j+1] = temp; //插入該元素}}
從空間效率看,直接插入排序僅使用了乙個輔助單元,故空間複雜度為: o(1).
從時間效率看,直接插入排序是有雙重迴圈組成,外層的for迴圈進行了n-1趟;內層while迴圈用於確定待插入記錄的具體位置並在保證有序的情況下空出插入的位置,其主要操作時進行關鍵字的比較和記錄的後移。而比較的次數和後移次數則取決於待排序序列中個記錄關鍵字的初始序列,可分三種情況討論:
(1)最好的情況:待排序列已按關鍵字有序,每趟次只需要1次比較和0次移動。
總比較次數: n-1次
總移動次數:0次
(2)最壞的情況:待排序序列按關鍵字逆序,這時每趟都要將待排序插入元素插入到有序序列的第乙個記錄位置,即第 i 趟操作要將記錄r[i]插入到r[0]的位置,這需要同前面的i個記錄進行i次關鍵字比較.移動記錄的次數和移動結束將temp變數賦給r[j+1]為:i+1次
總比較次數:
總移動次數:
(3)平均情況:可取(1)(2)這兩種極端情況的平均值,約n2/4。因此直接插入排序的時間複雜度為o(n2).插入排序是乙個穩定排序方法
折半插入排序:在直接插入排序中待排序元素被分為有序序列集合和無序序列集合。排序基本操作是向有序序列中插入乙個r[i],我們可以採用折半查詢來確定r[i]在有序序列中的位置從而減少查詢的次數。
插入排序的演算法如下:
#include
void b_insertsort(int a,int n);
int main()
; b_insertsort(array,8);
for (i=0;i<8;i++)
return0;}
void b_insertsort(int a,int n)
else
high = mid-1;
}for(j=i-1;j>=high+1;j--)
a[high+1] = temp;}}
採用折半插入排序的方法可以減少關鍵字的比較次數,但是記錄移動次數還是跟直接插入排序相同,外層迴圈n-1次,故時間複雜度仍為o(n2)。折半插入排序也是乙個穩定的排序方法。 直接插入排序和折半插入排序
1.直接插入排序 1.1插入排序 insertion sort 的基本思想 每次將乙個待排序的記錄,按其關鍵字大小插入到前面已經排序好的序列中,直到全部記錄插入完成為止.1.2 基本過程 假設待排序的記錄存放在陣列r 1.n 中。初始時,r 1 自成1個有序區,無序區為r 2.n 從i 2起直到i ...
排序之直接插入排序和折半插入排序
直接插入排序時將乙個記錄插入到乙個已經有序的的表或者陣列中,從而得到乙個新的有序的表或者陣列。就像打牌一樣,拿到一張牌後,要往手中的牌裡插,使手中的牌還是有序的。假如手中有4,6,7三張牌,現在拿到的下一張牌是5,那麼肯定要插在4之後,直接插入排序也是這個道理。假如現在有陣列 直接插入排序的過程如下...
直接插入排序與折半插入排序
首先看一下例子,將資料乙個個的插入到乙個列表中,插入後這個列表就排序好了 注意 這個列表是遞增的,而且記憶體空間已分配好,只是沒有填充真正的資料,如下 int insertsort mergetype l,int data for j l len 1 j 0 j else return 0 測試用例...