插入排序
概念
插入排序(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。
-
插入排序适用于:小规模数据数据或者基本有序
时十分高效。