• 八大排序方法汇总(选择排序,插入排序-简单插入排序、shell排序,交换排序-冒泡排序、快速排序、堆排序,归并排序,计数排序)


    2013-08-22 14:55:33

    八大排序方法汇总(选择排序-简单选择排序、堆排序,插入排序-简单插入排序、shell排序,交换排序-冒泡排序、快速排序,归并排序,计数排序)。

    插入排序还可以和折半查找相结合,提高查找插入位置的速度,也就是折半插入排序,此处没有给出这种方法的相应代码。

    对排序算法,可从以下几个方面评价:

    1. 时间复杂度;
    2. 空间复杂度;
    3. 稳定性。

    代码(测试暂未发现问题,欢迎交流指正!):

      1 #include <iostream>
      2 #include <cassert>
      3 #include <ctime>
      4 #include <bitset>
      5 using namespace std;
      6 
      7 typedef int DataType;
      8 const int MaxSize = 1000000;
      9 const int SortCutOff = 50;
     10 
     11 //产生在[lowBound,upperBound - 1]区间的随机数
     12 int RandomIntGenerate(int lowBound, int upperBound)
     13 {    
     14     return (lowBound + (RAND_MAX * rand() + rand()) % (upperBound - lowBound + 1) );
     15 }
     16 
     17 
     18 //数组显示
     19 void DisplayArray(DataType array[],int len)
     20 {
     21     assert(NULL != array && len > 0);
     22 
     23     for (int i = 0;i < len;++i)
     24     {
     25         cout<<array[i]<<"	";
     26     }
     27     cout<<endl;
     28 }
     29 
     30 //简单选择排序
     31 void SelectSort(DataType *unStorted,size_t n)
     32 {
     33     assert(NULL != unStorted && n > 0);
     34 
     35     size_t i;
     36     size_t j;
     37     size_t minIndex = 0;
     38 
     39     for (i= 0;i < n - 1;++i)
     40     {
     41         minIndex = i;
     42         for (j = i + 1;j < n;++j)
     43         {
     44             minIndex = unStorted[minIndex] < unStorted[j] ? minIndex : j;
     45         }
     46 
     47         swap(unStorted[i],unStorted[minIndex]);  //没有判断i与minIndex是否相等
     48     }
     49 }
     50 
     51 //简单插入排序
     52 void InsertSort(DataType *unStorted,size_t n)
     53 {
     54     assert(NULL != unStorted && n > 0);
     55 
     56     size_t i;
     57     int j;   //不能定义为size_t,因为for循环的结束条件需要将j减为-1作为结束条件
     58     DataType dataToInsert = 0;
     59 
     60     for (i= 0;i < n - 1;++i)
     61     {
     62         dataToInsert = unStorted[i + 1];
     63         for (j = i;j >= 0;--j)
     64         {
     65             if (unStorted[j] > dataToInsert)
     66             {
     67                 unStorted[j + 1] = unStorted[j];
     68             }
     69             else
     70             {
     71                 break;
     72             }
     73         }
     74         unStorted[j + 1] = dataToInsert;   //注意此处为j + 1,而非j
     75     }
     76 }
     77 
     78 //插入排序-shell排序
     79 //简单插入排序在输入为基本有序的情况下,性能最好,
     80 //shell排序每次大步长下的排序,相当于通过分组对数组预处理,使其基本有序
     81 void ShellSort(DataType *unStorted,size_t n)
     82 {
     83     assert(NULL != unStorted && n > 0);
     84 
     85     size_t step = n / 2;
     86     size_t k;
     87     size_t i;
     88     int j;   //不能定义为size_t,因为for循环的结束条件需要将j减为-1作为结束条件
     89     DataType dataToInsert = 0;
     90 
     91     while (step >= 1)  //n为1时,step为0,不进入while循环就返回;
     92     {
     93         for (k = 0;k < step;++k )
     94         {
     95             for (i= 0;i < n - step;i += step)
     96             {
     97                 dataToInsert = unStorted[i + step];
     98                 for (j = i;j >= 0;j -= step)
     99                 {
    100                     if (unStorted[j] > dataToInsert)
    101                     {
    102                         unStorted[j + step] = unStorted[j];
    103                     }
    104                     else
    105                     {
    106                         break;
    107                     }
    108                 }
    109                 unStorted[j + step] = dataToInsert;   //注意此处为j + 1,而非j
    110             }
    111         }
    112         step /= 2; 
    113     }
    114 }
    115 
    116 //交换排序-冒泡排序
    117 void BubbleSort(DataType *unStorted,size_t n)
    118 {
    119     assert(NULL != unStorted && n > 0);
    120 
    121     size_t i;
    122     size_t j;    
    123 
    124     for (i = n - 1;i >= 1;--i)
    125     {
    126         for (j = 0;j < i;++j)
    127         {
    128             if (unStorted[j] > unStorted[j + 1])
    129             {
    130                 swap(unStorted[j],unStorted[j + 1]);
    131             }
    132         }
    133     }
    134 }
    135 
    136 //快速排序的划分函数
    137 size_t Partion(DataType *unStorted,size_t begin,size_t end)
    138 {
    139     assert(begin <= end); //begin end都是定义为size_t的,因此不需要检查
    140     
    141     size_t i = begin;
    142     size_t j = end;
    143     //size_t pivot = i;
    144     size_t pivot = RandomIntGenerate(begin,end);  //枢轴为随机的,使得快速排序的划分尽可能对称
    145     swap(unStorted[i],unStorted[pivot]);
    146 
    147     while (i < j)
    148     {
    149         while (j > i && unStorted[j] > unStorted[i])
    150         {
    151             --j;
    152         }
    153         
    154         if (j > i)
    155         {
    156             swap(unStorted[i],unStorted[j]);
    157             pivot = j;
    158             ++i;
    159         }
    160 
    161         while (i < j && unStorted[i] < unStorted[j])
    162         {
    163             ++i;
    164         }
    165 
    166         if (j > i)
    167         {
    168             swap(unStorted[i],unStorted[j]);
    169             pivot = i;
    170             --j;
    171         }
    172     }
    173     //return i;
    174     //return j;
    175     return pivot;
    176 }
    177 
    178 //交换排序-快速排序
    179 void QuickSort(DataType *unStorted,size_t begin,size_t end)
    180 {
    181     assert(NULL != unStorted);
    182 
    183     //assert(begin >= 0 && end >= 0);  //begin end都是定义为size_t的,因此不需要检查
    184 
    185     if (begin >= end)
    186     {
    187         return;
    188     }
    189 
    190     int mid = Partion(unStorted,begin,end);    
    191 
    192     if (begin < mid)
    193     {
    194         QuickSort(unStorted,begin,mid - 1);
    195     }
    196 
    197     //QuickSort(unStorted,begin,mid - 1);  //若mid为0,size_t类型的mid减1会出问题,因此用begin < mid判断
    198     QuickSort(unStorted,mid + 1,end);
    199 }
    200 
    201 //归并两个数组
    202 void Merge(DataType *unStorted,size_t begin,size_t mid,size_t end)
    203 {
    204     assert(NULL != unStorted);
    205     assert(begin <= mid && mid <=end);
    206 
    207     DataType *resArray = new DataType[end - begin + 1];
    208     DataType *res = resArray;
    209 
    210     size_t lowIndex = begin;
    211     size_t highIndex = mid + 1;
    212 
    213     while (lowIndex <= mid && highIndex <= end)
    214     {
    215         if (unStorted[lowIndex] <= unStorted[highIndex])
    216         {
    217             *res++ = unStorted[lowIndex++];
    218         }
    219         else
    220         {
    221             *res++ = unStorted[highIndex++];
    222         }
    223     }
    224 
    225     while (lowIndex <= mid)
    226     {
    227         *res++ = unStorted[lowIndex++];
    228     }
    229 
    230     while (highIndex <= end)
    231     {
    232         *res++ = unStorted[highIndex++];
    233     }
    234 
    235     res = resArray;
    236 
    237     for (size_t index = begin;index <= end;++index)
    238     {
    239         unStorted[index] = *res++;
    240     }
    241 
    242     delete [] resArray;
    243 }
    244 
    245 //归并排序的非递归实现,自底向上归并
    246 void MergeSortNonRecursive(DataType *unStorted,size_t n)
    247 {
    248     assert(NULL != unStorted);
    249 
    250     size_t begin = 0;
    251     size_t mid = 0;
    252     size_t end = 0;
    253 
    254     size_t step = 1;
    255 
    256     while (step < n)
    257     {
    258         begin = 0;
    259         mid = begin + step - 1;
    260         end = begin+ 2 * step - 1;
    261 
    262         while (mid < n)
    263         {
    264             end = end > (n - 1) ? (n - 1) : end;  //防止end越界
    265 
    266             Merge(unStorted,begin,mid,end);
    267 
    268             begin = end + 1;    //不是begin = begin + step + 1;
    269             mid = begin + step - 1;
    270             end = begin+ 2 * step - 1;
    271         }
    272         step *= 2;
    273     }
    274 }
    275 
    276 //归并排序的非递归实现,自顶向下归并,分治法
    277 void MergeSort(DataType *unStorted,size_t begin,size_t end)
    278 {
    279     assert(NULL != unStorted);
    280 
    281     if (begin >= end)
    282     {
    283         return;
    284     }
    285 
    286     size_t mid = begin + (end - begin) / 2;
    287     MergeSort(unStorted,begin,mid);
    288     MergeSort(unStorted,mid + 1,end);  //若mid为size_t类型最大值,mid + 1就会越界,此时end已经越界
    289     Merge(unStorted,begin,mid,end);
    290 }
    291 
    292 //堆调整
    293 //参数n为数组中最大小标,如数组有n+1个元素,最大下标为n
    294 //posToAdjust为需要调整的位置的下标
    295 void HeapAdjust(DataType *unStorted,size_t n,size_t posToAdjust)
    296 {
    297     assert(NULL != unStorted);  //在调用的函数中已经有,可以删去
    298 
    299     size_t lchildIndex = 2 * posToAdjust + 1;
    300     size_t rchildIndex = 2 * posToAdjust + 2;
    301 
    302     size_t maxPosition = posToAdjust;
    303 
    304     //while (lchildIndex <= n || rchildIndex <= n)
    305     while (lchildIndex <= n)  //此处只要lchildIndex <= n ,即可进入循环
    306     {
    307         if (lchildIndex <= n && unStorted[lchildIndex] > unStorted[maxPosition])
    308         {
    309             maxPosition = lchildIndex;
    310         }
    311         //else if (rchildIndex <= n && unStorted[rchildIndex] > unStorted[maxPosition])
    312         if (rchildIndex <= n && unStorted[rchildIndex] > unStorted[maxPosition])  //不是else if 
    313         {
    314             maxPosition = rchildIndex;
    315         }
    316 
    317         if (maxPosition != posToAdjust)
    318         {
    319             swap(unStorted[posToAdjust],unStorted[maxPosition]);
    320             
    321             posToAdjust = maxPosition;      //更新posToAdjust,可以用递归,即HeapAdjust(unStorted,n,maxPosition);
    322             lchildIndex = 2 * maxPosition + 1;
    323             rchildIndex = 2 * maxPosition + 2;
    324         }
    325         else
    326         {
    327             break;
    328         }
    329     }
    330 }
    331 
    332 //堆排序
    333 //参数n为数组中最大小标,如数组有n+1个元素,最大下标为n
    334 void HeapSort(DataType *unStorted,size_t n)
    335 {
    336     assert(NULL != unStorted);
    337 
    338     int index;
    339 
    340     for (index = (n - 1) / 2;index >= 0;--index)  //index需要减到0,因此不能定义为size_t
    341     {
    342         HeapAdjust(unStorted,n,index);
    343     }
    344 
    345     for (index = n;index >= 1;--index)
    346     {
    347         swap(unStorted[0],unStorted[index]);
    348         HeapAdjust(unStorted,index - 1,0);  //不是HeapAdjust(unStorted,index,0);
    349     }
    350 }
    351 
    352 //计数排序,基本实现
    353 //此处的基数排序的使用场合:
    354 //输入为正数;
    355 //    输入不重复;
    356 //输入的最大数与输入的个数基本相等时空间利用率最高,也就是输入为0~n内的n个不重复的正数
    357 void CountSortBasic_1(DataType *unStorted,size_t n)
    358 {
    359     assert(NULL != unStorted);
    360 
    361     size_t *hash = new size_t [n + 1];
    362     size_t cnt = 0;
    363     int index =  0;
    364 
    365     for (index = 0;index <= n;++index)
    366     {
    367         hash[index] = 0;
    368     }
    369 
    370     for (index = 0;index < n;++index)  //index < n而非index <= n,因为此处访问的是unStorted[index],最大下标为n-1
    371     {
    372         ++hash[ unStorted[index] ];
    373     }
    374 
    375     for (index = 0;index <= n;++index)
    376     {
    377         if (hash[ index ] != 0)   //判断index是否出现
    378         {
    379             unStorted[cnt++ ] = index;  
    380         }
    381     }
    382 
    383     delete [] hash;
    384 }
    385 
    386 //计数排序,位图实现
    387 void CountSort(DataType *unStorted,size_t n)
    388 {
    389     assert(NULL != unStorted);
    390 
    391     bitset<MaxSize> hash;
    392     
    393     size_t cnt = 0;
    394     int index =  0;
    395 
    396     hash.reset();
    397 
    398     for (index = 0;index < n;++index)  //index < n而非index <= n,因为此处访问的是unStorted[index],最大下标为n-1
    399     {
    400         hash.set(unStorted[index]);
    401     }
    402 
    403     for (index = 0;index <= n;++index)
    404     {
    405         if ( hash.test(index) )
    406         {
    407             unStorted[cnt++ ] = index;  
    408         }
    409     }
    410 }
    411 
    412 //测试“脚手架”
    413 void TestSortDriver()
    414 {    
    415     /*DataType *unsortedArray = new DataType[MaxSize];
    416     size_t lengthOfUnsortedArray;*/
    417     size_t programToTest;
    418     
    419     int MinRandomInt;
    420     int MaxRandomInt;
    421     size_t i;
    422     int timeStart = 0;
    423     double timeCostAverage = 0;
    424 
    425     //用于计数排序时的输入
    426     DataType  unsortedArray[10]= {2,0,9,8,4,5,3,7,1,6};
    427     size_t lengthOfUnsortedArray = 10;
    428     
    429 
    430     cout<<"please enter the length Of UnsortedArray,MinRandomInt and MaxRandomInt :"<<endl;
    431     cin>>lengthOfUnsortedArray>>MinRandomInt>>MaxRandomInt;
    432     cout<<"please enter the identifier of the program to test (end with ctrl+z): "<<endl;
    433     while (cin>>programToTest)
    434     {
    435         for (i = 0;i < lengthOfUnsortedArray;++i)  //准备待排序数组
    436         {
    437             unsortedArray[i] = RandomIntGenerate(MinRandomInt,MaxRandomInt);
    438         }
    439 
    440         cout<<"the unsorted array is :"<<endl;
    441         DisplayArray(unsortedArray,lengthOfUnsortedArray);
    442 
    443         timeStart = clock();
    444         switch (programToTest)
    445         {
    446             case 11: 
    447                 cout<<"Test SelectSort..."<<endl;
    448                 SelectSort(unsortedArray,lengthOfUnsortedArray);
    449                 break;
    450 
    451             case 21: 
    452                 cout<<"Test InsertSort..."<<endl;
    453                 InsertSort(unsortedArray,lengthOfUnsortedArray);
    454                 break;
    455 
    456             case 22: 
    457                 cout<<"Test ShellSort..."<<endl;
    458                 ShellSort(unsortedArray,lengthOfUnsortedArray);
    459                 break;
    460 
    461             case 31: 
    462                 cout<<"Test BubbleSort..."<<endl;
    463                 BubbleSort(unsortedArray,lengthOfUnsortedArray);
    464                 break;
    465 
    466             case 32: 
    467                 cout<<"Test QuickSort..."<<endl;
    468                 QuickSort(unsortedArray,0,lengthOfUnsortedArray - 1);
    469                 break;
    470 
    471             case 33: 
    472                 cout<<"Test HeapSort..."<<endl;
    473                 HeapSort(unsortedArray,lengthOfUnsortedArray - 1);
    474                 break;
    475 
    476             case 41: 
    477                 cout<<"Test MergeSortNonRecursive..."<<endl;
    478                 MergeSortNonRecursive(unsortedArray,lengthOfUnsortedArray);
    479                 break;
    480 
    481             case 42: 
    482                 cout<<"Test MergeSort..."<<endl;
    483                 MergeSort(unsortedArray,0,lengthOfUnsortedArray - 1);
    484                 break;
    485 
    486 
    487             case 51: 
    488                 cout<<"Test CountSort..."<<endl;
    489                 CountSort(unsortedArray,lengthOfUnsortedArray);
    490                 break;
    491                 
    492             default:
    493                 break;
    494         }
    495 
    496         timeCostAverage = 1e9 * ( clock() - timeStart ) / ( CLOCKS_PER_SEC * lengthOfUnsortedArray );
    497         cout<<"the average time cost per data is : "<<timeCostAverage<<" ns"<<endl;
    498 
    499         for (i = 0;i < lengthOfUnsortedArray - 1;++i)
    500         {
    501             if (unsortedArray[i] > unsortedArray[i + 1])
    502             {
    503                 cout<<"sort bug i = "<<i<<endl;
    504             }
    505         }
    506 
    507         cout<<"the sorted array is :"<<endl;
    508         DisplayArray(unsortedArray,lengthOfUnsortedArray);
    509 
    510         cout<<endl;
    511         cout<<"please enter the identifier of the program to test (end with ctrl+z): "<<endl;
    512     }
    513 
    514     //delete [] unsortedArray;
    515 }
    516 
    517 int main()
    518 {
    519     TestSortDriver();
    520 
    521     return 0;
    522 }
  • 相关阅读:
    通过docker构建zabbix监控系统
    python中执行shell命令
    silverlight计时器的使用
    Silverlight学习笔记2:Silverlight中使用多线程实现倒计时
    silverlight全屏模式
    ASP.NET后台调用JavaScript
    JavaScript容易误解的概念
    Silverlight学习笔记1:创建一个Silverlight应用程序
    JavaScript中==和===的区别
    利用Visual Studio International Pack 实现对汉字的简单操作
  • 原文地址:https://www.cnblogs.com/youngforever/p/3275003.html
Copyright © 2020-2023  润新知