zoukankan      html  css  js  c++  java
  • 高效排序——希尔排序

    希尔排序是一种高性能的排序算法 ,其核心思想在于:

    1.将数组分割为若干子数组,对每个子数组进行简单算法排序(如插入,梳排序均可);

    2.将排序后的子序列合并,继续重复步骤1;

    直到所分的数组为1组。,算法结束。

           那么上述中,如何分组呢?分组方式见《C++数据结构与算法》393页最下面的划分方式,当然对于希尔排序而言,目前并没有一种理论上最优的划分方式,书上提供的是一种较为优秀的划分方式。

    下面直接上代码:

      1 # include"iostream"
      2 # include "vector"
      3 # include "ctime"
      4 # include "cstdlib"  // 如果我们想通过随机数来验证我们的想法。应该预先给vecot分配内存
      5 # include "cmath"
      6 
      7 using namespace std;
      8 void insert_sort(vector<int> & );
      9 void ChooseSort(vector<int> &);
     10 void BubbleSort(vector<int> &);
     11 void CombSort(vector<int> & );
     12 void ShellSort(vector<int> &);
     13 int main()
     14 {
     15     const int MAX_NUMBER = 10000;//生成的随机数的个数
     16     const int MIN_VALUE = 1;   //随机数值的下界
     17     const int MAX_VALUE = 30000;//随机数值的上界
     18     vector<int> a;
     19     a.reserve(MAX_NUMBER);//预先分配内存你,预防迭代器的失效。否则内存搬移,迭代器容易失效
     20 
     21     // 采用控制台输入的方式 
     22     //int temp;
     23     //while (cin >> temp)
     24     //{
     25     //    a.push_back(temp);
     26     //    if (cin.get() == '
    ') //注意这种用法,用的很多。
     27     //    {
     28     //        break;
     29     //    }
     30     //}
     31 
     32     //采用随机数生成法。
     33     srand((unsigned)time(NULL));//根据时钟生成不同的种子,保证每次运行程序产生不同的随机数
     34     for (int i = 1; i <= MAX_NUMBER; i++)
     35     {
     36         int temp;
     37         temp = (rand() % (MAX_VALUE - MIN_VALUE + 1)) + MIN_VALUE;//生成[MIN_VALUE,MAX_VALUE]之间的整数随机数
     38         a.push_back(temp);
     39     }
     40     //cout << "The initial order: ";    数据量太大,不适合输出
     41     //vector<int>::iterator ia = a.begin();
     42     //for (; ia != a.end(); ia++)
     43     //{
     44     //    cout << *ia << " ";
     45     //}
     46     //cout << endl;
     47     vector<int> b(a);
     48     vector<int> c(a);
     49     vector<int> d(a);
     50     vector<int> e(a);
     51     //show the initial order of the vector
     52     //cout << "The initial order before Sorting : ";
     53     //vector<int> ::iterator ia = a.begin();
     54     //for (; ia != a.end(); ia++)
     55     //{
     56     //cout << *ia << " ";
     57     //}
     58     //cout << endl;
     59     // 插入排序测试
     60     clock_t start, finish;
     61     double runtime;
     62     start = clock();
     63     insert_sort(a);
     64     finish = clock();
     65     runtime = (double)(finish - start) / CLOCKS_PER_SEC;
     66     cout << "The time of Insert Sort algorithm is:" << runtime << "s" << endl;
     67     // 选择排序测试
     68     start = clock();
     69     ChooseSort(b);
     70     finish = clock();
     71     runtime = (double)(finish - start) / CLOCKS_PER_SEC;
     72     cout << "The time of Choose Sort algorithm is:" << runtime << "s" << endl;
     73     // 冒泡排序测试
     74     start = clock();
     75     BubbleSort(c);
     76     finish = clock();
     77     runtime = (double)(finish - start) / CLOCKS_PER_SEC;
     78     cout << "The time of Bubble Sort algorithm is:" << runtime << "s" << endl;
     79     // 梳排序测试
     80     start = clock();
     81     CombSort(d);
     82     finish = clock();
     83     runtime = (double)(finish - start) / CLOCKS_PER_SEC;
     84     cout << "The time of Comb Sort algorithm is:" << runtime << "s" << endl;
     85     //希尔排序
     86     start = clock();
     87     ShellSort(e);
     88     finish = clock();
     89     runtime = (double)(finish - start) / CLOCKS_PER_SEC;
     90     cout << "The time of Shell Sort algorithm is:" << runtime << "s" << endl;
     91     system("pause");
     92     return 0;
     93 }
     94 //插入排序
     95 void insert_sort(vector<int> & sort_a)  ///注意,采用vector<int> 是可以作为参数进行传递的,那么是否可以作为返回类型使用呢?
     96 {
     97     int a_size ,temp;
     98     a_size = sort_a.size();
     99     for (int i = 1,j; i < a_size; i++)//注意,将j放在这里声明,不要放在下一个循环中声明,否则会造成多次声明?(但是作用域没变,多次声明应该被禁止,所以没有多次声明?)
    100     {
    101         temp = sort_a[i];
    102         for (j = i; (j > 0) && (sort_a[j - 1] > temp); j--)//这里先后顺序的差别,导致了数组的越界,
    103         {   
    104             sort_a[j] = sort_a[j-1];
    105         }
    106         sort_a[j] = temp;
    107     }
    108     //return sort_a;//说明可以将vector<int> 本身作为函数的返回值使用,但是需要清楚的是:返回的时候,内存实际上发生了局部变量复制,所以是否考虑返回引用???
    109 }
    110 //选择排序
    111 void ChooseSort(vector<int> & sort_a)
    112 {
    113     int a_size,MinNum;
    114     a_size = sort_a.size();
    115     for (int i = 0, j; i < a_size; i++)
    116     {
    117         int Loc = i;
    118         MinNum = sort_a[i];//本质是随机迭代器的使用
    119         //temp = sort_a[i];
    120         for (j = i+1; j < a_size; j++)
    121         { 
    122             if (sort_a[j] < MinNum)
    123             {
    124                 MinNum = sort_a[j];
    125                 Loc = j;
    126             }
    127         }
    128         //sort_a[i] = MinNum;//用于交换,但是本身自带的函数可以实现
    129         //sort_a[Loc] = temp;
    130         if (i != Loc)
    131         {
    132             swap(sort_a[i], sort_a[Loc]);//vector自带的东西
    133         }
    134     }
    135 }
    136 //冒泡排序
    137 void BubbleSort(vector<int> & sort_a)
    138 {
    139     int a_size;
    140     a_size = sort_a.size();
    141     for (int j = 0; j < a_size-1; j++)
    142     {
    143         for (int i = 0; i < a_size - 1-j; i++)
    144         {
    145             if (sort_a[i]>sort_a[i + 1])
    146                  swap(sort_a[i], sort_a[i + 1]);
    147         }
    148     }
    149 }
    150 //梳排序
    151 void CombSort(vector<int> & sort_a)
    152 {
    153     int step,j,k;
    154     step = sort_a.size();
    155     while ((step = int(step / 1.3)) >0)
    156     {
    157         for (j = sort_a.size() - 1; j >= step; j--)
    158         {
    159             k = j - step;
    160             if (sort_a[j] < sort_a[k])
    161             {
    162                 swap(sort_a[j], sort_a[k]);
    163             }
    164         }
    165     }
    166 }
    167 
    168 //希尔排序
    169 void ShellSort(vector<int> & sort_a)
    170 {
    171     int a_size;
    172     a_size = sort_a.size();//得到数组大小
    173     vector<int> ht;
    174     ht.resize(floor(log(a_size)/log(3)));//为增量数组预先分配空间
    175     ht[0] =1;//为何这样会出错???预分配空间后为何不能使用随机访问的机制???
    176     for (int i = 1; i<=ht.size()-1; i++)
    177     {
    178         ht[i] = 3 * ht[i - 1] + 1;
    179     }
    180     int ht_size = ht.size();
    181     vector<int> new_a;
    182     new_a.resize(a_size);
    183     for (int count = ht.size(), temp; count >= 1; count--)
    184     {
    185         temp = ht[count - 1];//temp的值决定了当前会被分成多少组
    186         //vector<int>a_divide;
    187         vector<vector<int>> aMatrix(temp, vector<int>(ceil(a_size / (1.0*temp))));//定义一个二维数组,
    188         for ( int i = 0; i < temp; i++)
    189         {
    190             int j;
    191             for (j = 0; (i + j*temp) < a_size; j++)
    192             {
    193                 aMatrix[i][j] = sort_a[i + j*temp];//将应该分为同一组的数据挑选出来    
    195             }
    196             if (ceil(a_size / (1.0*temp))>j)
    197             {
    198                 aMatrix[i][j] = 33333;//用于解决有0的问题
    199             }
    200            ;//问题是,本身有些空间存在0,这样写,将本身没有的0元素也进行了排序
    201         }
    202         //截止到这里,程序是没有问题的,也就是大部分是正确的,但是下面存在的问题是:数组中的0怎么办
    203         for(int k = 0, q = 0; k < ceil(a_size / (1.0*temp)); k++)
    204         {
    205             for (int p = 0; p < temp; p++)
    206             {
    207                 sort_a[q] = aMatrix[p][k];
    208                 q = q + 1;
    209                 if (q >= a_size)
    210                     break;
    211             }
    212             if (q >= a_size)
    213                 break;
    214         }
    215     }
    216         
    217 }

    实际上,上述给出很多排序算法的代码。

    169-215行为希尔排序算法的实现,对算法的各个部分进行解读:

    179行以前,求解每次分组的次数;

    200行以前,将同一组的数据提取出来,组成一个矩阵,每行表示同一组的,不同行表示不同分组,对每行的数据采取梳排序

    200行以后,将输入向量更新为矩阵列向量的拼接值

    重复迭代,直到h =1;

    针对希尔排序,其主要思想是一种分治的思想,给出上述排序算法效率的对比:

    该次测试中,随机数的个数为10000个,从结果中可以看出,希尔排序效率最高,但其和梳排序的效率较为接近(思考原因)

    在手撸希尔排序算法的过程中,遇到了很多c++中的问题,在此给出以下说明:

    ht.resize(floor(log(a_size)/log(3)));这句代码的本意是给数组ht预分配空间,开始使用的是ht.reserve(),但发现这样写,在调试的时候,导致ht[0] =1;出错,这说明并没有达到我们想要的结果。百度了下,发现:

    可见,使用reserve()并不会改变vector的大小,并不会和我们想的那样在内存中开辟出一片空间给vector。因此,若我们需要开辟一块可用空间,应该用resize()。那reserve()的作用是什么呢?(悬而未决)

    vector<vector<int>> aMatrix(temp, vector<int>(ceil(a_size / (1.0*temp))));定义了一个temp×ceil(a_size / (1.0*temp))大小的二维数组aMatrix,注意这是使用vector定义的二维数组,需要注意的是vector允许这种嵌套定义。

    另一个点在于CombSort(aMatrix[i]),CombSort的形参形式为数组引用,但这里传递是一个1维指针,说明某种意义上两者可以相互转换。但这个本质上说明了一个二维数组,只取一维其实就是一个指针。

    
    

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • 相关阅读:
    sql 触发器
    索引使用原则
    索引原理
    索引
    wpf Datagrid 的全选
    WPF ChangePropertyAction中TargetName和TargetObject的区别
    mvvm 模板中事件没有执行的解决方案
    wpf窗口禁止最大化但允许调整大小
    Process打开文件
    installshield 6109错误解决方案
  • 原文地址:https://www.cnblogs.com/shaonianpi/p/10981632.html
Copyright © 2011-2022 走看看