排序算法(1)

#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;
}
启发
  1. 函数指针做参数: 见runtime()函数;
  2. 随机数的生成: srand(time(0))要放在循环之外,否者生成的各个rand()都相同;
  3. 记录时间差: clock()函数;
  4. 输出到文件: fstream流;
注:

详见《数据结构与算法分析–c++语言描述》第四版,Mark Allen Weiss著, 冯舜玺译。

猜你喜欢

转载自blog.csdn.net/lituusliu/article/details/80423046