原博客:白话经典算法系列之八 MoreWindows白话经典算法之七大排序总结篇
//最佳步长:https://zh.wikipedia.org/wiki/希尔排序
#include <iostream>
#include <vector>
using namespace std;
void shellsort(vector<int> &vi){
if(vi.size()<=1) return ;
int n=vi.size();
for(int step=n/2;step>0;step/=2){
for(int i=0;i<step;++i){//1
for(int j=i+step;j<n;j+=step){//2
//在当前层做插入排序,相当于直接插入排序的第一种优化。见直接插入排序。
if(vi[j]<vi[j-step]){//如果前一元素大于当前的元素
int temp=vi[j];
int k=j-step;
while(k>=0 && vi[k]>temp){
vi[k+step]=vi[k];
k=k-step;
}
vi[k+step]=temp;
}
}
}
}
}
//优化1:结构上的优化,shellsort中1与2处的for可以合并一下。
void shellsort1(vector<int> &vi){
if(vi.size()<=1) return ;
int n=vi.size();
for(int step=n/2;step>0;step/=2){
for(int j=step;j<n;++j){
if(vi[j]<vi[j-step]){
int temp=vi[j];
int k=j-step;
while(k>=0 && vi[k]>temp){
vi[k+step]=vi[k];
k=k-step;
}
vi[k+step]=temp;
}
}
}
}
//优化2:结构上的优化,用swap来使代码更精简,但是效率会变低一点
void shellsort2(vector<int> &vi){
if(vi.size()<=1) return ;
int n=vi.size();
for(int step=n/2;step>0;step/=2)
for(int j=step;j<n;++j)
for(int k=j-step;k>=0 && vi[k]>vi[k+step];k-=step)
swap(vi[k],vi[k+step]);
}
int main(){
vector<int> vi;
vi={1,8,2,3,7,6,9,5,4};
// shellsort(vi);
// shellsort1(vi);
shellsort2(vi);
for(auto ieh: vi)
cout<<ieh<<" ";
cout<<endl;
return 0;
}