代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 vector<int> G; 5 6 // 间隔为dis的插入排序 7 static void insertionSort(vector<int> &v, int dis){ 8 int sz = v.size(); 9 for(int i=dis;i<sz;i++){ 10 int num = v[i]; 11 int j = i - dis; 12 while(j>=0 && v[j]>num){ 13 v[j+dis] = v[j]; 14 j -= dis; 15 } 16 v[j+dis] = num; 17 } 18 return; 19 } 20 21 static void shellSort(vector<int> &v){ 22 int sz = v.size(); 23 // 生成数列 G = {1, 4, 13, 40, 121...} 24 for(int i=1;i<sz;i=3*i+1) 25 G.push_back(i); 26 27 int szg = G.size(); 28 for(int i=szg-1;i>=0;i--) 29 insertionSort(v, G[i]); 30 31 return; 32 } 33 34 int main(){ 35 int n; 36 while(cin>>n){ 37 vector<int> v(n); 38 for(int i=0;i<n;i++) 39 cin>>v[i]; 40 shellSort(v); 41 for(int num : v) 42 cout<<num<<","; 43 } 44 return 0; 45 }
希尔排序就是先将间隔为dis的子数组进行插入排序,然后逐渐缩小dis到1,即整个数组排序完毕。
由于子序列用的插入排序,所以希尔排序是稳定的
时间复杂度基本维持在O(n^1.25)
这里要注意,如果G的选取是{1, 2, 4, 8}这种g=1之前几乎不需要排序的数列,希尔排序的效率会大打折扣