zoukankan      html  css  js  c++  java
  • 排序算法的比较---插入、选择、快排

    实验代码:

    #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)错误经验分析:

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

     

  • 相关阅读:
    mysql sql语句多表合并UNION ALL和UNION
    ajax向后台传递数组参数并将后台响应的数据赋值给一个变量供其它插件使用
    java web项目中后台控制层对参数进行自定义验证 类 Pattern
    java后台实体类设置默认值
    app连接线上数据库进行本地接口测试
    idea常用快捷键
    百度搜索小脚本
    有道翻译小脚本
    洛谷 P3275 [SCOI2011]糖果
    洛谷 P2048 BZOJ 2006 [NOI2010]超级钢琴
  • 原文地址:https://www.cnblogs.com/k-q-l/p/3633901.html
Copyright © 2011-2022 走看看