从0开始学算法--排序(1.4希尔排序)

从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之前几乎不需要排列的数组,希尔排序的效率大打折扣