改进方法参照:http://faculty.simpson.edu/lydia.sinapova/www/cmsc250/LN250_Weiss/L12-ShellSort.htm#increments
/*************************************************************************
> File Name: shellsort.cpp
> Author:keson
> Mail:keson@bupt.edu.cn
> Created Time: 2014年11月30日 星期日 10时05分18秒
************************************************************************/
#include<iostream>
#include<vector>
#include<fstream>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
//一般的希尔排序函数
template<typename Comparable>
void shellsort(vector<Comparable> &a)
{
for(int gap=a.size()/2;gap>0;gap/=2)
for(int i=gap;i<a.size();++i)
{
Comparable tmp=std::move(a[i]);
int j=i;
for(;j>=gap&&tmp<a[j-gap];j-=gap)
a[j]=std::move(a[j-gap]);
a[j]=std::move(tmp);
}
}
//得到希尔排序的序列号: 1,5,19,41,109.......
//可参考http://faculty.simpson.edu/lydia.sinapova/www/cmsc250/LN250_Weiss/L12-ShellSort.htm#increments
template<typename Comparable>
vector<int> getseq(const vector<Comparable> &a)
{
vector<int> vec;
int val1=0,val2=0;
for(int i=0;val1<a.size()/2&&val2<a.size()/2;i++)
{
val1=9*(pow(4,i)-pow(2,i))+1;
val2=pow(2,i+2)*(pow(2,i+2)-3)+1;
vec.push_back(val1);
vec.push_back(val2);
}
sort(vec.begin(),vec.end(),greater<int>());
return vec;
}
//用得到的序列号进行希尔排序
template<typename Comparable>
void shellsort1(vector<Comparable> &a)
{
vector<int> seq=getseq(a);
int index=0;
for(int gap=seq[index];index<seq.size();gap=seq[++index])
{
for(int i=gap;i<a.size();++i)
{
Comparable tmp=std::move(a[i]);
int j=i;
for(;j>=gap&&tmp<a[j-gap];j-=gap)
a[j]=std::move(a[j-gap]);
a[j]=std::move(tmp);
}
}
}
int main()
{
ofstream out;
out.open("NUMBER_FILE");
int SIZE=50000000;
while(SIZE)
{
out<<rand()%10000<<" ";
SIZE--;
}
out.close();
ifstream in;
in.open("NUMBER_FILE");
ofstream out2("SORT1");
vector<int>vec;
int val;
while(in>>val)
vec.push_back(val);
vector<int> vec1(vec);
clock_t start_time=clock();
//原来的希尔排序
shellsort(vec);
clock_t end_time=clock();
cout<<"Running time is:"<<
static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC<<" S"<<endl;
clock_t start_time1=clock();
//改进的希尔排序
shellsort1(vec1);
clock_t end_time1=clock();
cout<<"QUICK Running time is "<<
static_cast<double>(end_time1-start_time1)/CLOCKS_PER_SEC<<" S"<<endl;
//测试两种排序结果是否一样
int flag=0;
for(int i=0;i<vec.size();i++)
{
if(vec[i]!=vec1[i])
flag++;
}
cout<<flag<<endl;
for(auto c:vec)
out2<<c<<" ";
in.close();
out2.close();
}