从0开始学算法--排序(1.4希尔排序)
算法理解:
希尔排序是插入排序的优化,因为插入排序可以高效的处理比较有序的数据,希尔排序充分发挥了这一个特长,在希尔排序中,程序会重复精选以间隔未h的元素未对象的插入排序。
如下图,对A[]={4,8,9,1,10,6,2,5,3,7};进行H={4,3,1}的希尔排序。
#include <algorithm> #include <iostream> #include <cstring> #include <vector> #include <cstdio> #include <cmath> #include <queue> using namespace std; const int maxn=1e5+1; long long cnt; int l; int A[maxn] int n; vector<int >G; //指定间隔g的篡改人排序 void insertionSort(int A[],int n,int g){ for(int i=g;i<n;i++){ int v=a[i]; int j=i-g; while(j>=0&&a[j]>v){ A[j+g]=a[j]; j-=g; cnt++; } A[j+g]=v; } } void shellSort(int A[],int n){ //生成数列1,4,13,40,121,364,1093 for(int h=1;;){ if(h>n)break; G.push_back(h); h=3*h+1; } for(int i=G.size()-1;i>=0;i--){//逆序指定g insertionSort(A,n,G[i]); } } int main(){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&A[i]); } cnt=0; shellSort(A,n); for(int i=G.size()-1;i>=0;i--){ printf("%d",G[i]); if(i)printf(" "); } printf("\n"); printf("%d\n",cnt); for(int i=0;i<n;i++){ printf("%d\n",a[i]); } return 0; }
1.想完成数据排序必须再最后执行g=1,即普通的插入排序法
2.G数组的选择方法有很多,当G为1,4,13,40,121,等即gn+1=gn*3+1时,复杂度基本维持再O(N1.25)
3.遇到2的幂指数,再g=1之前几乎不需要排列的数组,希尔排序的效率大打折扣