1.直接插入排序
分析:a[n]有n个元素 a[0...n-1] 从 i=1...n-1 a[i]依次与 a[0...n-2]数字进行比较
发现后面的数字大于前面的数字交换位置,每一次比较,与前面的数字x比较,小于等于x的话往前推a[j]=a[j+1],当大于a[j]时候 a[j+1]=a[i]插入
//插入排序 #include<iostream> using namespace std; void gcd(int a[],int start,int end){ int tmp; int i,j; //从第二个元素开始i=1---n-1 for(i=start+1;i<end;i++){ tmp=a[i]; for(j=i-1;tmp<a[j]&&j>=start;j--){ a[j+1]=a[j]; } a[j+1]=tmp; } } int main() { int n; cin>>n; int a[n]; for(int i=0;i<n;i++) cin>>a[i]; gcd(a,0,n); for(int i=0;i<n;i++) cout<<a[i]<<" "; }
2.折半插入排序:在插入排序寻找位置改成折半查找
针对a[i],查找出a[j],使a[j]<=a[i],对a[j]之后的数字全部移动a[j]=a[j+1],a[i]插入到a[j]之后,
//插入排序 #include<iostream> using namespace std; void gcd(int a[],int start,int end){ int tmp; int i,j,right,left,mid; for(i=start+1;i<end;i++){ tmp=a[i]; left=start; right=i-1; while(left<=right){ mid=(left+right)/2; if(tmp<a[mid]) right=mid-1; else left=mid+1; // for(j=i-1;j>=left;j--) a[j+1]=a[j]; } for(j=i-1;j>=left;j--) a[j+1]=a[j]; a[left]=tmp; } } int main() { int n; cin>>n; int a[n]; for(int i=0;i<n;i++) cin>>a[i]; gcd(a,0,n); for(int i=0;i<n;i++) cout<<a[i]<<" "; }
3.希尔shell插入排序
a.由于直接插入排序算法简单,在n很小的时候效率比较高,
b.正序越多,效率越高
#include<iostream> using namespace std; void shell(int a[],int start,int end,int gap){ int tmp; int i,j; for(i=start+gap;i<end;i++){//每gap段比较 tmp=a[i]; for(j=i-gap;tmp<a[j]&&j>=start;j-=gap) a[j+gap]=a[j]; a[j+gap]=tmp; } } void gcd(int a[],int start,int end){ int gap=end-start; while(gap>1){ gap=gap/3+1; shell(a,start,end,gap); } } int main() { int n; cin>>n; int a[n]; for(int i=0;i<n;i++) cin>>a[i]; gcd(a,0,n); for(int i=0;i<n;i++) cout<<a[i]<<" "; }