插入排序算法主要有直接插入排序算法、折半查找算法、希爾插入排序算法。算法
·直接插入排序:數組
將記錄插到已排好的有序表中,從而獲得一個新的、記錄數量增1的有序表。spa
【算法思想】指針
1)設待排序的記錄存放在數組r[1..n],r[1]是一個有序序列。code
2)循環n-1次,每次使用順序查找法,查找r[i](i=2,3...,n)在已排好的序列r[1..i-1]中的插入位置,而後將r[i]插入錶廠爲i-1的有序序列r[1..i-1]直到將r[n]插入錶廠爲n-1的有序序列r[1..n-1],最後獲得一個表長尾n的有序序列。blog
以下圖所示待排序記錄的關鍵字序列爲{49,38,65,97,13,27,49}使用直接插入排序法進行排序的過程:排序
【算法描述】ip
void InsertSort (SqList &L){ //對順序表L作直接插入排序 for(i=2;i<=L.length;++i) if(L.r[i].key<L.r[i-1].key){//實現r[i]插入有序表 L.r[0]=L.r[i];//將待插入的記錄暫存到監視哨中 L.r[i]=L.r[i-1];//r[i-1]向後移動 for(j=i-2;:L.r[0].key<L.r[j].key;--j)//從後向前尋找插入位置 L.r[j+1}=L.r[j];//記錄逐個後移,直到找到插入位置 L.r[j+1]=L.r[0];//將r[0]即原r[i],插入到正確位置 } }
1)是穩定排序class
2)算法簡單,容易實現List
3)也適用於鏈式存儲結構,知識在單鏈表上不是移動記錄,只要修改相應的指針。
4)更適合於初始記錄基本有序的狀況,當初始記錄無序,n較大時,此算法時間複雜度較高,不宜採用。
·折半插入排序
利用「折半查找」來實現的排序算法。
【算法思想】
1)將待排序的記錄存放在數組r[1..n]中,r[1]是一個有序序列。
2)循環n-1次,每次使用折半查找法,查找r[i](i=2,3,..n)在已排好的序列r[1..i-1],直到將r[n]插入表長爲n-1的有序序列r[1..n-1],最後獲得一個表長爲n的有序序列。
看下面一個小例子:
【算法描述】
void BInsertSort(SqList &L){//對順序表L作折半查找 for(i=2;i<=L.length;++i){ L.r[0]=L.r[i];//將待插入的記錄暫存到監視哨中 low=1;high=i-1;//置查找區間初值 while(low<=high){//在r[row..high]中折半查找插入位置 m=(low+high)/2;//折半 if(L.r[0].key<L.r[m].key)high=m-1;//插入點在前一子表 else low=m+1;//插入點在後面子表 } for(j=i-1;j>high+1;--)L.r[j+1]=L.r[j];//記錄後移 L.r[high+1]=L.r[0];//將r[0]即原r[i],插入到正確位置 } }
【算法特色】
1)是穩定的
2)由於要進行折半查找,因此只能用於順序結構,不能用於鏈式結構
3)適合初始記錄無序,n較大時的狀況。
·希爾排序
希爾排序又稱「縮小增量排序」是插入排序的一種。
【算法思想】
希爾排序實質上是採用分組插入的方法。先將整個待排序記錄序列分割成幾組,從而減小參與直接超人排序的數據量,對每組分別進行直接插入排序,而後增長每組的數據量,從新分組。
以下實例:
【算法描述】
void ShellInsert(SqList &L,int dk){//對順序表L作一趟增量是dk的希爾插入排序 for(i=dk+1;i<L.length;++i) if(L.r[i].key<L.r[i-dk].key){//需將L.r[i]插入有序增量表 L.r[0]=L.r[i];//暫存在r[0] for(j=i-dk;j>0&&L.r[0].key<L.r[j].key;j-=dk) L.r[j+dk]=L.r[j];//記錄後移,直到找到插入位置 L.r[j+dk]=L.r[0]; } } void ShellSort(SqList &L,int dt[],int t){ for(k=0;k<t;++k) ShellInsert(L,dt[k]);//一趟增量爲dt[t]的希爾排序 }
【算法特色】
1)記錄跳躍式第移動致使排序算法是不穩定的
2)只能用於順序結構,不能用於鏈式結構
3)增量序列能夠有多種取法,但應該使增量序列中的值沒有除1以外的公因式,而且最後一個增量值必須等於1
4)記錄總的比較次數和移動次數都比直接插入排序要少,n越大時,效果越明顯。
【小結】
總之,插入排序的基本思想是,每一趟將一個待排序的記錄,按其關鍵字的大小插入到已經排好序的一組記錄的適當位置上,直到全部待排序記錄所有插入爲止。