排序算法的比较---插入、选择、快排

实验代码:

#include<iostream>

#include<cstdlib>

#include<time.h>

#define N 100000

using namespace std;

 

class Array

{

    public: Array();                                                  //构造函数

            void Sort_decent();                                       //辅助构造函数产生非递增序列

            void Sort_one();                                          //排序方案一:插入排序

           

            void Sort_two();                                           //排序方案二:选则排序

            void Sort_three_SampleOne(int *Sample,int start,int end);  //排序方案三:快速排序

            void Sort_three_SampleOne_time();                          //为乱序数组快排计时

            void Sort_three_SampleTwo_time();                          //为顺序数组快排计时

           

           

   

    private: void Show_result(int *p);                              //如果需要可以使用来显示排序结果:

                                                                    //因为测试数据数量较多,所以略去这一步

                                                                    //小规模测试可以考虑使用(后面给出了其代码实现)

            

             int sarray[N];                                         //随机数组

             int darray[N];                                         //非递增数组

};

 

 

 

Array::Array()                        

{

    for(int i=0;i<N;i++)               //产生随机数组

    {

         srand(i);     

         sarray[i] = darray[i] = rand()%N;

    }

    Sort_decent();                                     //将数组darray非递增排序

}

 

void Array::Sort_decent()                         

{

    int temp;

    for(int i=0;i<N-1;i++)

    {

        for(int j=i;j<N;j++)

            if(darray[i]<darray[j])

            {

                temp = darray[i];

                darray[i] = darray[j];

                darray[j] = temp;

            }

    }

}

 

void Array::Sort_one()                           //排序方案一:插入排序

{   int Sample_one[N];

    int Sample_two[N];                           //样本数组:sarray与darray的两个样本,下同

    int i,j,k,l;

    for( i=0 ;i<N;i++)

    {

        Sample_one[i] = sarray[i];

        Sample_two[i] = darray[i];

    }

    clock_t start1 = clock();                        //记录排序起始时间,下同

     for( j=1;j<N;j++ )                                //对乱序数组排序

     {

          k = Sample_one[j];

          l = j-1;

          while((k>=0)&&(Sample_one[l]>k))

          {

              Sample_one[l+1] = Sample_one[l];

              l--;

          }

          Sample_one[l+1] = k;

     }

    clock_t end1=clock();                          //记录排序终了时间,下同

//  Show_result(Sample_one);                        

    cout<<"乱序数组插入排序用时: "<<end1-start1<<" ms"<<endl;

   

//  Show_result(Sample_two);

    clock_t start2=clock();                      

     for( j=1;j<N;j++ )                          //对顺序数组排序

     {

         k = Sample_two[j];

          l = j-1;

          while((k>=0)&&(Sample_two[l]>k))

          {

              Sample_two[l+1] = Sample_two[l];

              l--;

          }

          Sample_two[l+1] = k;

     }

    clock_t end2=clock();

//  Show_result(Sample_two);

    cout<<"顺序数组插入排序用时: "<<end2-start2<<" ms"<<endl;

}

 

void Array::Sort_two()                                //排序方案二:选择排序

{

     

    int Sample_one[N];

    int Sample_two[N];

    int i;

    for( i=0 ;i<N;i++)

    {

        Sample_one[i] = sarray[i];

        Sample_two[i] = darray[i];

    }

    clock_t start1 = clock();

           for ( i = 0; i < N; i++)

            {

                int min = Sample_one[i], min_index = i;

                for (int j = i; j < N; j++)

                {

                    if (Sample_one[j] < min)

                    {

                        min = Sample_one[j];

                        min_index = j;

                    }

                }

                if (min_index != i)

                {

                    int temp = Sample_one[i];

                    Sample_one[i] = Sample_one[min_index];

                    Sample_one[min_index] = temp;

                }

            }

        clock_t end1=clock();

//      Show_result(Sample_one);

        cout << "乱序数组选择排序用时: "<<end1-start1<<" ms"<<endl;

         

           clock_t start2 = clock();

           for( i=0; i < N; i++)

            {

                int min = Sample_two[i], min_index = i;

                for (int j = i; j < N; j++)

                {

                    if (Sample_two[j] < min)

                    {

                        min = Sample_two[j];

                        min_index = j;

                    }

                }

                if (min_index != i)

                {

                    int temp = Sample_two[i];

                    Sample_two[i] = Sample_two[min_index];

                    Sample_two[min_index] = temp;

                }

             }

        clock_t end2=clock();

//      Show_result(Sample_two);

        cout<<"顺序数组选择排序用时: "<<end2-start2<<" ms"<<endl;

}

 

void Array::Sort_three_SampleOne(int *Sample_one,int start,int end)             //排序方案三:快速排序

{

   

    int i,j,std_data;

    if(start < end)                                                                               

    {                                                                          //第一趟排序

        i = start;

        j = end;

        std_data = Sample_one[start];

        while(i<j)

        {

            while(Sample_one[j]>=std_data&&i<j)

            {

                j--;

            }

            if(i<j) Sample_one[i++] = Sample_one[j];

            while(Sample_one[i]<=std_data&&i<j)

            {

                i++;

            }

            if(i<j) Sample_one[j--] = Sample_one[i];

        }

        Sample_one[i] = std_data;

        Sort_three_SampleOne(Sample_one,start,i-1);

        Sort_three_SampleOne(Sample_one,i+1,end);

    }

   

   

}

 

 

 

void Array::Sort_three_SampleOne_time()                                     //记录乱序数组排序时间

{

    int Sample_one[N];

    for(int i=0 ;i<N;i++)

    {

        Sample_one[i] = sarray[i];

    }

    clock_t start1 = clock();

    Sort_three_SampleOne(Sample_one,0,N-1);

    clock_t end1 = clock();

    cout<<"乱序数组快速排序用时: "<<end1-start1<<" ms"<<endl;

 

}

 

void Array::Sort_three_SampleTwo_time()                                    //记录顺序数组排序时间

{

    int Sample_two[N];

    for(int i=0 ;i<N;i++)

    {

        Sample_two[i] = darray[i];

    }

    clock_t start2 = clock();

    Sort_three_SampleOne(Sample_two,0,N-1);

    clock_t end2 = clock();

    cout<<"顺序数组快速排序用时: "<<end2-start2<<" ms"<<endl;

 

}

 

 

 

 

void Array::Show_result(int *p)

{

   

    for(int i=0;i<N;i++)

        cout<<p[i]<<" ";

}

 

 

 

int main(void)

{

    Array array;                    

    array.Sort_one();

    array.Sort_two();

    array.Sort_three_SampleOne_time();

    array.Sort_three_SampleTwo_time();

   

    return 0;

}

 

代码在Vs2012上编译运行通过,运行时可自行修改N的值从而改变排序规模

总结:

(1)算法部分:

这个程序的编写是用面向对象的思想进行的,Array类有Sort_one()

Sort_two()、Sort_three()三个行为即插入、选择、快速排序以及两个数组成员sarray,darray.从数据结构方面的知识我们知道插入排序的时间复杂度为O(n^2),从实验结果可以看出它并不适合数据量很大的排序,而选择排序与插入排序的时间复杂度同为O(n^2)所以也不适合大量数据的排序,但是从截图可以看出在乱序数组排序时,插入排序较选择排序更具有优势,快速排序对乱序数组的排序具有十分明显的优势,其时间复杂度为O(nLogn),从实验结果来看也的确如此,随着数据量的增大快排很显然是最好的选择,但是也该注意到快排对于顺序数组的排序时间复杂度的数量级也是O(n^2),所以具体使用哪种排序方式还得具体情况具体分析。

(2)类的设计部分:

之前有考虑将排序前后的结果输出,但是实验要求是测试大规模数据的排序,所以数组的输出会使得结果显得十分累赘而没有突出重点,但还是给出了其实现,所以Array类的Show_result()成员,仅供使用者依据需要自行使用(最好用于小规模的数据输出)。另外的不足之处在于,Sort_one()、Sort_two()、Sort_three()三个成员都要对sarray与darray两个私有成员中的数据进行处理,可谓“僧多粥少”,所以在设计时每个方法都定义了两个局部变量Sample_one与Sample_two用于复制sarray与darray,但是这样无疑是中糟糕的方案,其实自己的想法是每个成员处理了数组之后能够将其复原,这样可以节省内存分配所用时间,但是知识与技术有限,没能这样实现,所以以后还得更加努力学习C++面向对象的编程思想。

(3)错误经验分析:

在程序结果正确输出前,犯了一个十分严重的错误,就是未意识到快速排序的递归性,而将时间测量也放在了快排函数的实现中,而结果输出出错。就这点我深刻意识到了递归函数的功能一定要是十分单一的,只能解决一个问题,不断将其规模变小,这个过程中不能添加其它的过程,否则其它也会参与递归,这是应该十分警惕的。

 

原文地址:https://www.cnblogs.com/k-q-l/p/3633901.html