#include<iostream>
#include<fstream>
#include<ctime>
#include<array>
#include<vector>
using namespace std;
const int MAXDATA = 10000;
template<typename U> bool sorted(vector<U> &t);
template<typename U> void bubbleSort(vector<U> &t);
template<typename U> void selectSort(vector<U> &t);
template<typename U> void insertSort(vector<U> &t);
template<typename U> void shellSort(vector<U> &t);
template<typename U> void heapSort(vector<U> &t);
template<typename U> void mergeSort(vector<U> &t,int low, int high);
template<typename U> void quickSort(vector<U> &t,int low, int high);
template<typename U> void displayContents(vector<U> &t, ostream &out=cout);
template<typename U> vector<U>* generate(int n, int MAX);//生成n位大小为0~MAX的随机整数
template<typename U> double runtime(void(*)(vector<U> &t), vector<U> &t);
template<typename U> double runtime(void(*sortFunc)(vector<U> &t, int, int), vector<U> &t);
int main()
{
/*
ofstream out("data_sort_522", ios_base::out);
if(!out.is_open())
throw("file was not open!");
out.close();
*/
srand(time(0));
vector<int> *exp=generate<int>(1000,MAXDATA);
vector<int> *exp0=new vector<int>{*exp},
*exp1=new vector<int>{*exp},
*exp2=new vector<int>{*exp},
*exp3=new vector<int>{*exp},
*exp4=new vector<int>{*exp},
*exp5=new vector<int>{*exp},
*exp6=new vector<int>{*exp};
cout<<"\nraw_data---------------------------\n";
displayContents(*exp);
cout<<"\nbubbleSort-------------------------\n";
double t0=runtime(bubbleSort, *exp0);
cout<<"time used: "<<t0<<"ms"<<endl;
cout<<"outcome:\n";
if(sorted(*exp0)) displayContents(*exp0);
else cerr<<"the sequences are not sorted correctly.\n";
cout<<"\nselectSort-------------------------\n";
double t1=runtime(selectSort, *exp1);
cout<<"time used: "<<t1<<"ms"<<endl;
cout<<"outcome:\n";
if(sorted(*exp1)) displayContents(*exp1);
else cerr<<"the sequences are not sorted correctly.\n";
cout<<"\ninsertSort-------------------------\n";
double t2=runtime(insertSort, *exp2);
cout<<"time used: "<<t2<<"ms"<<endl;
cout<<"outcome:\n";
if(sorted(*exp2)) displayContents(*exp2);
else cerr<<"the sequences are not sorted correctly.\n";
cout<<"\nshellSort--------------------------\n";
double t3=runtime(shellSort, *exp3);
cout<<"time used: "<<t3<<"ms"<<endl;
cout<<"outcome:\n";
if(sorted(*exp3)) displayContents(*exp3);
else cerr<<"the sequences are not sorted correctly.\n";
cout<<"\nheapSort---------------------------\n";
double t4=runtime(heapSort, *exp4);
cout<<"time used: "<<t4<<"ms"<<endl;
cout<<"outcome:\n";
if(sorted(*exp4)) displayContents(*exp4);
else cerr<<"the sequences are not sorted correctly.\n";
cout<<"\nmergeSort---------------------------\n";
double t5=runtime(mergeSort, *exp5);
cout<<"time used: "<<t5<<"ms"<<endl;
cout<<"outcome:\n";
if(sorted(*exp5)) displayContents(*exp5);
else cerr<<"the sequences are not sorted correctly.\n";
cout<<"\nquickSort---------------------------\n";
double t6=runtime(quickSort, *exp6);
cout<<"time used: "<<t6<<"ms"<<endl;
cout<<"outcome:\n";
if(sorted(*exp6)) displayContents(*exp6);
else cerr<<"the sequences are not sorted correctly.\n";
delete exp;
delete exp0;
delete exp1;
delete exp2;
delete exp3;
delete exp4;
delete exp5;
delete exp6;
return 0;
}
template<typename U> bool sorted(vector<U> &t)
{
if(t.cbegin()==t.cend())
throw("the set of sequences is empty!");
for(auto pv=t.cbegin()+1;pv!=t.cend();pv++)
if(*(pv-1)>*pv)
return false;
return true;
}
template<typename U> void bubbleSort(vector<U> &t)
{
int n=t.size();
for(int i=0;i<n;i++)
{
bool sign=true;
for(int j=n-1;j>i;j--)
if(t[j]<t[j-1])
{
swap(t[j],t[j-1]);
sign=false;
}
if(sign)
break;
}
}
template<typename U> void selectSort(vector<U> &t)
{
for(auto vp1=t.begin();vp1!=t.end();vp1++)
{
decltype(t.begin()) ppos=vp1;
for(auto vp2=vp1+1;vp2!=t.end();vp2++)
{
if(*vp2<*ppos)
ppos=vp2;
}
if(ppos!=vp1) //交换值
{
auto tem=*vp1;
*vp1=*ppos;
*ppos=tem;
}
}
}
template<typename U> void insertSort(vector<U> &t)
{
if(t.cbegin()==t.cend())
throw("the set of sequences is empty!");
for(int i=1;i<(int)t.size();i++)
{
int j=i;
auto tem=std::move(t[j]);
for(; j>0 && tem<t[j-1]; j--)
t[j]=std::move(t[j-1]);
t[j]=std::move(tem);
}
}
template<typename U> void shellSort(vector<U> &t)
{
if(t.cbegin()==t.cend())
throw("the set of sequences is empty!");
for(int gap=t.size()>>1;gap>0;gap>>=1)
{
for(int i=gap; i<(int)t.size(); i++)
{
int j=i;
auto tem=std::move(t[j]);
for( ; j>=gap && tem<t[j-gap]; j-=gap)
t[j]=std::move(t[j-gap]);
t[j]=std::move(tem);
}
}
}
inline int leftChild(int i)
{
return 2*i+1;
}
//从下标 i 的非叶节点开始下渗;
//n 是二叉堆的逻辑大小;
template<typename U> void percDown(vector<U>& t, int i, int n)
{
int child;
auto temv=std::move(t[i]);
for(; leftChild(i)<n ; i=child)
{
child=leftChild(i);
if(child != n-1 && t[child] < t[child+1]) //存在右孩子
child++;
if(temv < t[child])
t[i]=std::move(t[child]);
else
break;
}
t[i]=std::move(temv);
}
template<typename U> void heapSort(vector<U> &t)
{
//build max heap;
//按下标从大到小的次序调节非叶节点:0~[N/2]-1;
int n=(int)t.size();
for(int i=n/2-1; i>=0; i--)
percDown(t, i, t.size());
//delete max
for(int i=n-1; i>0; i--)
{
swap(t[0], t[i]);
percDown(t, 0, i);
}
}
template<typename U> void mergeSort(vector<U> &t, int low, int high)
{
if(low>=high)
return;
int mid=(low+high)/2;
mergeSort(t, low, mid);
mergeSort(t, mid+1, high);
vector<U> *ptem{new vector<U>(high-low+1)};
int i, j ,k;
for(i=low, j=mid+1, k=0; i<=mid && j<=high; )
{
(*ptem)[k++]=(t[i]<t[j])?t[i++]:t[j++];
}
while(i<=mid)
(*ptem)[k++]=t[i++];
while(j<=high)
(*ptem)[k++]=t[j++];
for(int l=low,k=0;l<=high;l++)
t[l]=(*ptem)[k++];
delete ptem;
}
template<typename U> void quickSort(vector<U> &t,int low, int high)
{
if(low>=high)
return;
int i=low, j=high;
bool sign=true; //对应i++;
while(i!=j)
{
if(t[i]>t[j])
{
swap(t[i],t[j]);
sign=!sign;
}
sign?i++:j--;
}
quickSort(t,low,i-1);
quickSort(t,i+1,high);
}
template<typename U> vector<U>* generate(int n, int MAX)
{
vector<U> *ptem = new vector<U> (n);
for(auto &v:*ptem)
v=rand()%MAX; //rand():0~RAND_MAX;
return ptem;
}
template<typename U> void displayContents(vector<U> &t, ostream &out=cout)
{
for(auto v:t)
out<<v<<'\t';
out<<"\n";
}
template<typename U> double runtime(void(*sortFunc)(vector<U> &t), vector<U> &t)
{
clock_t start=clock();
sortFunc(t);
clock_t finish=clock();
return 1000.0*(finish-start)/CLOCKS_PER_SEC;
}
template<typename U> double runtime(void(*sortFunc)(vector<U> &t, int low, int high), vector<U> &t)
{
clock_t start=clock();
sortFunc(t,0,t.size()-1);
clock_t finish=clock();
return 1000.0*(finish-start)/CLOCKS_PER_SEC;
}
启发
- 函数指针做参数: 见runtime()函数;
- 随机数的生成: srand(time(0))要放在循环之外,否者生成的各个rand()都相同;
- 记录时间差: clock()函数;
- 输出到文件: fstream流;
注:
详见《数据结构与算法分析–c++语言描述》第四版,Mark Allen Weiss著, 冯舜玺译。