插入排序演算法(插入排序&折半插入排序&希爾排序)
阿新 • • 發佈:2020-09-13
插入排序
概念
插入排序(Insertion-Sort)的演算法描述是一種簡單直觀的排序演算法。它的工作原理是通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃描,找到相應位置並插入。
這裡我們採用順序表的儲存方式來儲存資料
具體實現步驟
- 將待排序序列第一個元素看做一個有序序列,把第二個元素到最後一個元素當成是未排序序列;
- 取出下一個元素,在已經排序的元素序列中從後向前掃描;
- 如果該元素(已排序)大於新元素,將該元素移到下一位置;
- 重複步驟3,直到找到已排序的元素小於或者等於新元素的位置;
- 將新元素插入到該位置後;
- 重複步驟2~5。
程式碼實現
#include<iostream> using插入排序namespace std; #define MAXSIZE 50 typedef int keyType; typedef string other; typedef struct { keyType key; other data; //其他資料 }arrayType; typedef struct{ arrayType r[MAXSIZE+1]; // r[0]閒置或者作為哨兵而存在 int length; }SqList; void Sort(SqList &p) { int j; for(int i=2;i<=p.length;i++) {if(p.r[i].key<p.r[i-1].key) { p.r[0].key=p.r[i].key; p.r[i].key = p.r[i-1].key; for(j = i-2;p.r[0].key<p.r[j].key;j--) { p.r[j+1].key = p.r[j].key; } p.r[j+1].key = p.r[0].key; } } } int main() {int n,i; SqList arry; cout<<"請輸入需要排序的個數:"<<endl; cin>>n;arry.length=n; cout<<"請依次輸入這"<<n<<"個數:"<<endl; for(i=0;i<n;i++) { cin>>arry.r[i+1].key; } Sort(arry); cout<<"排序後:"<<endl; for(i=1;i<=n;i++) { cout<<arry.r[i].key<<" "; } return 0; }
折半插入排序
概念
折半插入排序(Binary Insertion Sort)是對插入排序演算法的一種改進,所謂排序演算法過程,就是不斷的依次將元素插入前面已排好序的序列中。
排序思想
遍歷無序區間的所有元素,每次取無序區間的第一個元素Array[i],因為0~i-1是有序排列的,所以用中點m將其平分為兩部分,然後將待排序資料同中間位置為m的資料進行比較,若待排序資料較大,則low~m-1分割槽的資料都比待排序資料小,反之,若待排序資料較小,則m+1~high分割槽的資料都比 待排序資料大,此時將low或high重新定義為新的合適分割槽的邊界,對新的小分割槽重複上面操作。直到low和high 的前後順序改變,此時high+1所處位置為待排序資料的合適位置。
程式碼實現
#include<iostream> using namespace std; #define MAXSIZE 50 typedef int keyType; typedef string other; typedef struct { keyType key; other data; //其他資料 }arrayType; typedef struct{ arrayType r[MAXSIZE+1]; // r[0]閒置或者作為哨兵而存在 int length; }SqList; void Sort(SqList &p) { for(int i=2;i<=p.length;i++) { p.r[0].key=p.r[i].key; int low =1,high = i-1,m; if(p.r[i-1].key>p.r[i].key) { while(low<=high) { m =(low+high)/2; if(p.r[m].key<p.r[0].key) low = m+1; else high = m-1; } for(int j=i-1;j>high;j--) p.r[j+1].key = p.r[j].key; p.r[high+1]=p.r[0]; } } } int main() { int n,i; SqList arry; cout<<"請輸入需要排序的個數:"<<endl; cin>>n;arry.length=n; cout<<"請依次輸入這"<<n<<"個數:"<<endl; for(i=0;i<n;i++) { cin>>arry.r[i+1].key; } Sort(arry); cout<<"排序後:"<<endl; for(i=1;i<=n;i++) { cout<<arry.r[i].key<<" "; } return 0; }
希爾排序
概念
希爾排序又叫做縮小增量排序,其本質還是插入排序,只是在將待排序序列按照某種規則分成幾個子序列,分別對這幾個子序列進行直接插入排序,
排序思想
首先它把較大的資料集合分割成若干個小組(邏輯上分組),然後對每一個小組分別進行插入排序,此時,插入排序所作用的資料量比較小(每一個小組),插入的效率比較高
程式碼實現
1 #include<iostream> 2 using namespace std; 3 #define MAXSIZE 50 4 typedef int keyType; 5 typedef string other; 6 typedef struct 7 { 8 keyType key; 9 other data; //其他資料 10 }arrayType; 11 12 typedef struct{ 13 14 arrayType r[MAXSIZE+1]; // r[0]閒置或者作為哨兵而存在 15 int length; 16 }SqList; 17 18 void ShellInsert(SqList &p,int dk) 19 { 20 for(int i=dk+1;i<=p.length;i++) 21 { 22 if(p.r[i].key<p.r[i-dk].key) 23 { 24 p.r[0] = p.r[i]; 25 p.r[i]=p.r[i-dk]; 26 p.r[i-dk]=p.r[0]; 27 } 28 } 29 } 30 31 void ShellSort(SqList &p,int dt[],int t) 32 { 33 for(int k=0;k<t;k++) 34 { 35 ShellInsert(p,dt[k]); 36 } 37 } 38 int main() 39 { 40 int n,i; 41 SqList arry; 42 cout<<"請輸入需要排序的個數:"<<endl; 43 cin>>n;arry.length=n; 44 cout<<"請依次輸入這"<<n<<"個數:"<<endl; 45 for(i=0;i<n;i++) 46 { 47 cin>>arry.r[i+1].key; 48 } 49 //增量序列 50 int dt[3] = {5,3,1}; 51 ShellSort(arry,dt,3); 52 53 54 cout<<"排序後:"<<endl; 55 for(i=1;i<=n;i++) 56 { 57 cout<<arry.r[i].key<<" "; 58 } 59 60 return 0; 61 }
插入總結
- 希爾排序不可以用於鏈式結構
- 空間複雜度都是O(1)
- 時間複雜度:O(n2),O(n2),n(log2n)2。
-
插入排序適用於:小規模資料資料或者基本有序
時十分高效。