zoukankan      html  css  js  c++  java
  • 模板化的七种排序算法,适用于T* vector<T>以及list<T>

      最近在写一些数据结构以及算法相关的代码,比如常用排序算法以及具有启发能力的智能算法。为了能够让写下的代码下次还能够被复用,直接将代码编写成类模板成员函数的方式,之所以没有将这种方式改成更方便的函数模板纯属于偷懒,更方便于测试代码的有效性,等代码写完也懒得去改了。下面开始介绍这段代码,有什么不对的地方欢迎前来指正。

      一共写了七种排序,插入排序InsertSort、堆排序HeapSort、快速排序QuickSort、合并排序MergeSort,计数排序CountingSort,基数排序RadixSort,桶排序BucketSort。排序思想都是根据<<Introduction to Algorithms>>而来的,所以对于这本书里面的时间复杂度都是严格遵从的,本文就不详细介绍这些算法的思想和实现机制了。针对于这七种排序,先写一个非特化的模板类Sort空着,是为了能够让模板的特化正确通过编译,接着写三个特化版本的Sort类,三个特化的版本分别接受T* vector<T>以及list<T>作为模板形参,而其中的各个成员函数接受的参数也是这些类型。函数体没有写的情况大致如下:

      1 template<typename T>
      2 class Sort
      3 {
      4 
      5 };
      6 
      7 template<typename T>
      8 class Sort<T*>
      9 {
     10 public:
     11     void InsertSort(T* t, int length = 0)
     12     {
     13     }
     14 
     15     //the hardest part is to judge the correctness
     16     void MergeSort(T* t, int length = 0)
     17     {
     18     }
     19 
     20     void HeapSort(T* t, int length = 0)
     21     {
     22     }
     23 
     24     void QuickSort(T* t, int length = 0)
     25     {
     26     }
     27 
     28     void CountingSort(T* t, int length = 0)
     29     {
     30     }
     31 
     32     void RadixSort(T* t, int length = 0)
     33     {
     34     }
     35 
     36     void BucketSort(T* t, int length = 0)
     37     {
     38     }
     39 
     40 template<typename T>
     41 class Sort<std::vector<T>>
     42 {
     43 public:
     44     void InsertSort(std::vector<T>& t)
     45     {
     46     }
     47 
     48     void HeapSort(std::vector<T>& t)
     49     {
     50     }
     51 
     52     void QuickSort(std::vector<T>& t)
     53     {
     54     }
     55 
     56     void CountingSort(std::vector<T>&t)
     57     {
     58     }
     59 
     60     void RadixSort(std::vector<T>& t)
     61     {
     62     }
     63 
     64     void BucketSort(std::vector<T>& t)
     65     {
     66     }
     67 };
     68 
     69 template<typename T>
     70 class Sort<std::list<T>>
     71 {
     72 public:
     73     void InsertSort(std::list<T>& t)
     74     {
     75     }
     76 
     77     void MergeSort(std::list<T>& t)
     78     {
     79     }
     80      
     81     void HeapSort(std::list<T>& t)
     82     {
     83     }
     84 
     85     void QuickSort(std::list<T>& t)
     86     {
     87     }
     88 
     89     void CountingSort(std::list<T>& t)
     90     {
     91     }
     92 
     93     void RadixSort(std::list<T>& t)
     94     {
     95     }
     96 
     97     void BucketSort(std::list<T>& t)
     98     {
     99     }
    100 
    101 };

       对于编译期决定的类型T,基本数据类型之外,用户提供的自定义类只要重载了operator> operator< operator==...就能够直接使用这些函数。这是c++语言的特性,因为实现过程中使用了>和<来比较T,因此这个是需要的。对于T*版本的特化,因为数组本身就是通过下标运算来取得每个元素的,所以template<> Sort<T*>{}中的函数接受一个T类型指针和这个T类型数组的长度作为参数。

      由于vector这个容器的是一段连续分配的地址(如果想了解的童鞋可以去看看STL源码剖析),因此vector重载了operator[]以及operator+, operator- 这些可以直接根据index索引到目标地址的对象。这样一来template<> Sort<std::vector<T>>{}中七种排序函数都可以跟template<> Sort<T*>{}中的函数几乎一模一样,可以直接通过operator[]来获取元素。但是从最开始我是希望编写可复用的程序的,因此效率问题在我的首要考虑范围之内。因为vector的operator[]一样也是通过iterator来获取元素的,所以在Sort类中首先尝试了直接使用iterator来取得元素,在Sort<vector<T>>中的InsertSort就是这样来实现的,从代码的可读性方面来说要差点。

      而对于list容器来说,本身就是链式动态分配的内存,没有提供operator[]和operator+,operator-也是正常的,因此在Sort<list<T>>的函数实现中,没有办法使用t[i]这样的语法,因此针对list<T>的函数,一点也没有偷懒,都是使用iterator来实现的,与使用operator[]不同之处主要在于该iterator不能直接加上一个值,另一个就是iterator的边界条件比较麻烦,在iterator等于list的bigin()或者end()的时候,是不能够使用iterator--或者iterator++的,否则会触发list的断言。InsertSort算法的三种如下所示:

      1 #include <vector>
      2 #include <iostream>
      3 #include <list>
      4 #include <exception>
      5 #include <iterator>
      6 #include <math.h>
      7 
      8 template<typename T>
      9 class Sort
     10 {
     11 
     12 };
     13 
     14 template<typename T>
     15 class Sort<T*>
     16 {
     17 public:
     18     void InsertSort(T* t, int length = 0)
     19     {
     20         if (t == NULL)
     21         {
     22             std::cout << "are you fucking kidding me?";
     23         }
     24         else
     25         {
     26             //<<introduction to algorithm>> the array is from 1, we are from 0
     27             for (int i = 1; i<length; i++)
     28             {
     29                 T temp = t[i];
     30                 int j = i - 1;
     31                 while (j >= 0 && t[j]>temp)
     32                 {
     33                     t[j + 1] = t[j];
     34                     --j;
     35                 }
     36                 t[j + 1] = temp;
     37             }
     38         }
     39     }
     40 };
     41 
     42 #pragma region std::vector<T>
     43 template<typename T>
     44 class Sort<std::vector<T>>
     45 {
     46 public:
     47     typedef typename std::vector<T>::iterator iterator;
     48 public:
     49     //actually vector use the operator[] should be faster
     50     //the operator[] also used iterator
     51     void InsertSort(std::vector<T>& t)
     52     {
     53         if (t.size()>0)
     54         {
     55             for (std::vector<T>::iterator it = t.begin() + 1; it != t.end(); it++)
     56             {
     57                 std::vector<T>::iterator itFront = it - 1;
     58                 T temp = *(it);
     59 
     60                 while (*itFront > temp)
     61                 {
     62                     std::vector<T>::iterator itTemp = itFront;
     63                     itTemp++;
     64                     *itTemp = *itFront;
     65                     if (itFront != t.begin())
     66                     {
     67                         itFront--;
     68                         if (itFront == t.begin() && *itFront < temp)
     69                         {
     70                             itFront++;
     71                             break;
     72                         }
     73                     }
     74                     else
     75                     {
     76                         break;
     77                     }
     78                 }
     79                 *(itFront) = temp;
     80             }
     81         }
     82     }
     83 };
     84 #pragma endregion
     85 
     86 #pragma region std::list<T>
     87 template<typename T>
     88 class Sort<std::list<T>>
     89 {
     90     //for the list, we can't directly use the operator+/-,because it is the list
     91     //actually we can use the operator[] to change it, does list solved the problem?
     92     //not effective at all
     93     //we should support a method to increase or decrease the pointer(iterator)!
     94     typedef typename std::list<T>::iterator iterator;
     95 
     96 public:
     97     void InsertSort(std::list<T>& t)
     98     {
     99         for (std::list<T>::iterator it = t.begin(); it != t.end(); it++)
    100         {
    101             std::list<T>::iterator itFront = it;
    102             if (++it == t.end())
    103             {
    104                 break;
    105             }
    106             T temp = *it;
    107             it--;
    108 
    109             while (*itFront > temp)
    110             {
    111                 std::list<T>::iterator itTemp = itFront;
    112                 itTemp++;
    113                 *itTemp = *itFront;
    114                 if (itFront != t.begin())
    115                 {
    116                     itFront--;
    117                     if (itFront == t.begin() && *itFront < temp)
    118                     {
    119                         itFront++;
    120                         break;
    121                     }
    122                 }
    123                 else
    124                 {
    125                     break;
    126                 }
    127             }
    128             *itFront = temp;
    129         }
    130     }
    131 
    132 };
    133 
    134 #pragma endregion

      除了InsertSort之外的所有排序Sort<vector<T>>基本上都与T*相类似,而Sort<list<T>>则必须使用iteraotr来搞定。由于InsertSort是比较简单的插入排序,其效率也不是很高。除了这一种比较排序之外,还写了MergeSort,HeapSort以及QuickSort这三种比较算法。其中MergeSort和QuickSort都使用了分治的策略。而HeapSort则充分利用了数据结构来改善排序过程。这些思想在<<Introduction to Algrithms>>都十分详细。

      除了上面的比较排序除外,还写了三种线性时间排序算法:CountingSort,RadixSort和BucketSort。这三种算法都是有其局限性的,因为CountingSort是通过输入数组的值来建立对应的计数数组,然后算出每个数对应的位置,因此输入数组的值必须是int类型才行,甚至还必须要是正数。同样的问题在RadixSort算法中也是存在的,而本模板稍微做了两点优化:一是使用c++的RTTI机制中的typeid方法来判断类型,只有是int类型才有下一步。二是解决CountingSort和RadixSort的负数和值过大过小问题,采用的方法是分割开正数和负数,针对不同类型的数再取其最大最小值,将最小值映射到0,而将最大值映射到max-min。就搞定了这个问题,稍微优化了一点空间。

      对于BucketSort算法来说,完全利用的是数据结构的技巧来取得优势,三种特化的模板都是使用vector数组来实现的,本来是想要用双端链表来搞定的,这样效率高点,但是由于没有写针对于双端链表的sort算法,所以偷了回懒,直接用vector来搞定。这个算法也是最短的算法,思想也是最简单的。对于BucketSort算法的短板,就是搞不定除了基本数据类型之外的数据,因为还需要客户重载operator/,这个就比较麻烦了,估计很少有这个需求的用户类。

      下面则是全部的代码:

    点击下载代码

       1 #include <vector>
       2 #include <iostream>
       3 #include <list>
       4 #include <exception>
       5 #include <iterator>
       6 #include <math.h>
       7 
       8 template<typename T>
       9 class Sort
      10 {
      11 
      12 };
      13 
      14 template<typename T>
      15 class Sort<T*>
      16 {
      17 public:
      18     void InsertSort(T* t, int length = 0)
      19     {
      20         if (t == NULL)
      21         {
      22             std::cout << "are you fucking kidding me?";
      23         }
      24         else
      25         {
      26             //<<introduction to algorithm>> the array is from 1, we are from 0
      27             for (int i = 1; i<length; i++)
      28             {
      29                 T temp = t[i];
      30                 int j = i - 1;
      31                 while (j >= 0 && t[j]>temp)
      32                 {
      33                     t[j + 1] = t[j];
      34                     --j;
      35                 }
      36                 t[j + 1] = temp;
      37             }
      38         }
      39     }
      40 
      41     //the hardest part is to judge the correctness
      42     void MergeSort(T* t, int length = 0)
      43     {
      44         _MergeSort(t, 0, length - 1);
      45     }
      46 
      47     void HeapSort(T* t, int length = 0)
      48     {
      49         try
      50         {
      51             if (length>0)
      52             {
      53                 length = length - 1;
      54                 BuildHeap(t, length);
      55                 for (int i = length; i >= 0; i--)
      56                 {
      57                     T temp = t[0];
      58                     t[0] = t[i];
      59                     t[i] = temp;
      60                     Max_Heapify(t, 0, i - 1);
      61                 }
      62             }
      63         }
      64         catch (std::out_of_range e)
      65         {
      66             std::cout << "out_of_range error" << std::endl;
      67         }
      68     }
      69 
      70     void QuickSort(T* t, int length = 0)
      71     {
      72         _QuickSort(t, 0, length-1);
      73     }
      74 
      75     //this one can only work in integer, negetive value is also included
      76     void CountingSort(T* t, int length = 0)
      77     {
      78         if (typeid(T) == typeid(int))
      79         {
      80             //one iterator to check the min, max, the number of negetive value
      81             int count = 0;
      82             T* negetiveArray;
      83             T* positiveArray;
      84             //前一版本将比较的次数缩减到了3(n-2)/2次,但是行数太多
      85             for (int i = 0; i < length; i++)
      86             {
      87                 if (t[i] < 0)
      88                 {
      89                     count++;
      90                 }
      91             }
      92             negetiveArray = new T[count];
      93             positiveArray = new T[length - count];
      94             //split the array into the postive and negetive value arrays
      95             for (int i = 0, m = 0, n = 0; i < length; i++)
      96             {
      97                 if (t[i] < 0)
      98                 {
      99                     negetiveArray[m] = t[i];
     100                     m++;
     101                 }
     102                 else
     103                 {
     104                     positiveArray[n] = t[i];
     105                     n++;
     106                 }
     107             }
     108             T poMin = positiveArray[0], poMax = positiveArray[0];
     109             T neMin = negetiveArray[0], neMax = negetiveArray[0];
     110             for (int i = 0; i < count; i++)
     111             {
     112                 if (negetiveArray[i] < neMin)
     113                 {
     114                     neMin = negetiveArray[i];
     115                 }
     116                 if (negetiveArray[i] > neMax)
     117                 {
     118                     neMax = negetiveArray[i];
     119                 }
     120             }
     121             for (int i = 0; i < length - count; i++)
     122             {
     123                 if (positiveArray[i] < poMin)
     124                 {
     125                     poMin = positiveArray[i];
     126                 }
     127                 if (positiveArray[i] > poMax)
     128                 {
     129                     poMax = positiveArray[i];
     130                 }
     131             }
     132             //得到正负两个数组各自的最小最大差 并将两个数组映射到0-poMin;
     133             T poMinux = poMax - poMin;
     134             T neMinux = neMax - neMin;
     135 
     136             T* positiveArrayed = new T[length - count];
     137             int* countArray = new int[poMinux + 1];
     138             memset(countArray, 0, (poMinux + 1)*sizeof(T));
     139 
     140             for (int i = 0; i < length - count; i++)
     141             {
     142                 countArray[positiveArray[i] - poMin] ++;
     143                 //std::cout << countArray[i] << " ";
     144             }
     145             //此处与算法描述中不同的地方在于,countArray用于保存每个数存在的位置,但是该位置应该是从0开始的
     146             for (int i = 1; i <= poMinux; i++)
     147             {
     148                 //std::cout << countArray[i - 1] << " ";
     149                 countArray[i] = countArray[i] + countArray[i - 1];
     150                 countArray[i - 1]--;
     151             }
     152             countArray[poMinux]--;
     153             //将正数数组从后往前每一个数放到应该放的地方,之所以是从后往前是为了保持算法的稳定性
     154             for (int i = length - count - 1; i >= 0; i--)
     155             {
     156                 positiveArrayed[countArray[positiveArray[i] - poMin]] = positiveArray[i];
     157                 countArray[positiveArray[i] - poMin]--;
     158             }
     159 
     160             //负值数组开始的地方
     161             T* negetiveArrayed = new T[count];
     162             int* countArrayNe = new int[neMinux + 1];
     163             memset(countArrayNe, 0, (neMinux + 1)*sizeof(T));
     164 
     165             for (int i = 0; i < count; i++)
     166             {
     167                 countArrayNe[negetiveArray[i] - neMin]++;
     168             }
     169             for (int i = 1; i <= neMinux; i++)
     170             {
     171                 countArrayNe[i] += countArrayNe[i - 1];
     172                 countArrayNe[i - 1]--;
     173             }
     174             countArrayNe[neMinux]--;
     175 
     176             for (int i = count - 1; i >= 0; i--)
     177             {
     178                 negetiveArrayed[countArrayNe[negetiveArray[i] - neMin]] = negetiveArray[i];
     179                 countArrayNe[negetiveArray[i] - neMin]--;
     180             }
     181 
     182             //正负两个数组合并
     183             for (int i = 0, j = 0; i < length; i++)
     184             {
     185                 if (i < count)
     186                 {
     187                     t[i] = negetiveArrayed[i];
     188                 }
     189                 else
     190                 {
     191                     t[i] = positiveArrayed[j];
     192                     j++;
     193                 }
     194             }
     195 
     196             delete[] negetiveArray;
     197             delete[] positiveArray;
     198             delete[] countArray;
     199             delete[] countArrayNe;
     200             delete[] negetiveArrayed;
     201             delete[] positiveArrayed;
     202         }
     203         else
     204         {
     205             std::cout << "you are using non-int type array for Counting Sort" << std::endl;
     206         }
     207     }
     208 
     209     void RadixSort(T* t, int length = 0)
     210     {
     211         int count = 0;
     212         for (int i = 0; i < length; i++)
     213         {
     214             if (t[i] < 0)
     215             {
     216                 count++;
     217             }
     218         }
     219         T* positiveArray = new T[length - count];
     220         T* negetiveArray = new T[count];
     221 
     222         for (int i = 0, m=0, n=0; i < length; i++)
     223         {
     224             if (t[i] < 0)
     225             {
     226                 negetiveArray[m] = -t[i];
     227                 m++;
     228             }
     229             else
     230             {
     231                 positiveArray[n] = t[i];
     232                 n++;
     233             }
     234         }
     235         _RadixSort(positiveArray, length - count);
     236         _RadixSort(negetiveArray, count);
     237         for (int i = 0, m=count-1, n =0; i < length; i++)
     238         {
     239             if (i < count)
     240             {
     241                 t[i] = -negetiveArray[m];
     242                 m--;
     243             }
     244             else
     245             {
     246                 t[i] = positiveArray[n];
     247                 n++;
     248             }
     249         }
     250     }
     251 
     252     void BucketSort(T* t, int length = 0)
     253     {
     254         /*
     255         this one does't like other linear time sorting, the basic type are all received for the parameter
     256         and the class which supports operator[], operator - and operator > (< == ...).
     257         */
     258         //if we achieve the algrithm with T*, it will need more time and space to judge the length of array's array
     259         //struct, vector, list are all useful. this one is using the data structrue to decrease time;
     260         
     261         /*
     262         The first version is using struct to construct the bucket, then i found that i did't finish the sort for the 
     263         linked list (sort by the pointer of a linked list)
     264         */
     265 
     266         T max = t[0], min = t[0];
     267         for (int i = 0; i < length; i++)
     268         {
     269             if (t[i]>max)
     270             {
     271                 max = t[i];
     272             }
     273             if (t[i] < min)
     274             {
     275                 min = t[i];
     276             }
     277         }
     278         int minux = max - min +1;
     279         //std::vector<std::vector<T>> colArray;
     280         std::vector<T>* colArray = new std::vector<T>[length];
     281         //std::vector<T> rawArray;
     282         for (int i = 0; i < length; i++)
     283         {
     284             int index = (t[i] - min)*length / minux;
     285             std::vector<T> & rawArray = colArray[index];
     286             rawArray.push_back(t[i]);
     287         }
     288         for (int i = 0; i < length; i++)
     289         {
     290             std::vector<T>& rawArray = colArray[i];
     291             Sort<std::vector<T>>::InsertSort(rawArray);
     292         }
     293         for (int i = 0, index=0; i < length; i++)
     294         {
     295             std::vector<T> & rawArray = colArray[i];
     296             //int j = 0;
     297             for (std::vector<T>::iterator it = rawArray.begin(); it != rawArray.end(); it++)
     298             {
     299                 t[index] = *it;
     300                 index++;
     301             }
     302         }
     303         delete[] colArray;
     304     }
     305 
     306 private:
     307     void _MergeSort(T* t, int a, int b)
     308     {
     309         if (a<b)
     310         {
     311             int c = (a + b) / 2;
     312             _MergeSort(t, a, c);
     313             _MergeSort(t, c + 1, b);
     314             Merge(t, a, c, b);
     315         }
     316     }
     317 
     318     void Merge(T* t, int a, int c, int b)
     319     {
     320         int n1 = c - a + 1;
     321         int n2 = b - c;
     322         //here to create the array dynamicly, remember to delete it;
     323         T* temp1 = new T[n1 + 1];
     324         T* temp2 = new T[n2 + 1];
     325 
     326         for (int i = 0; i<n1; i++)
     327         {
     328             temp1[i] = t[a + i];
     329         }
     330         //the biggest value of positive int
     331         temp1[n1] = 2147483647;
     332         for (int i = 0; i<n2; i++)
     333         {
     334             temp2[i] = t[c + 1 + i];
     335         }
     336         temp2[n2] = 2147483647;
     337 
     338         int m = 0, n = 0;
     339         for (int i = a; i <= b; i++)
     340         {
     341             if (temp1[m] <= temp2[n])
     342             {
     343                 t[i] = temp1[m];
     344                 m++;
     345             }
     346             else if (temp1[m]>temp2[n])
     347             {
     348                 t[i] = temp2[n];
     349                 n++;
     350             }
     351         }
     352         //remember to clean it
     353         delete[] temp1;
     354         delete[] temp2;
     355     }
     356 
     357     //i-root re-heap;
     358     //abstract from the tree, but did not used tree; 
     359     void Max_Heapify(T* t, int i, int length)
     360     {
     361         int largest = 0;
     362         int l = GetLeftChild(i);
     363         int r = GetRightChild(i);
     364 
     365         if (l <= length && t[i] <t[l])
     366         {
     367             largest = l;
     368         }
     369         else
     370         {
     371             largest = i;
     372         }
     373 
     374         if (r <= length && t[largest] < t[r])
     375         {
     376             largest = r;
     377         }
     378 
     379         if (largest != i)
     380         {
     381             T temp = t[i];
     382             t[i] = t[largest];
     383             t[largest] = temp;
     384             Max_Heapify(t, largest, length);
     385         }
     386     }
     387 
     388     inline int GetLeftChild(int i)
     389     {
     390         return ((i + 1) << 1) - 1;
     391     }
     392 
     393     inline int GetRightChild(int i)
     394     {
     395         return (i + 1) << 1;
     396     }
     397 
     398     void BuildHeap(T* t, int length)
     399     {
     400         //after the length/2, then it should not be the tree node
     401         for (int i = length / 2; i >= 0; i--)
     402         {
     403             Max_Heapify(t, i, length);
     404         }
     405     }
     406 
     407     void _QuickSort(T* t, int a, int b)
     408     {
     409         if (a<b)
     410         {
     411             int s = Partition(t, a, b);
     412             _QuickSort(t, a, s-1);
     413             _QuickSort(t, s + 1, b);
     414         }
     415     }
     416 
     417     int Partition(T* t, int a, int b)
     418     {
     419         T split = t[a];
     420         //when the a equals b, a should be the split!
     421         while (a < b)
     422         {
     423             while (t[b] >= split && a < b)
     424             {
     425                 b--;
     426             }
     427             T temp = t[a];
     428             t[a] = t[b];
     429             t[b] = temp;
     430 
     431             while (t[a] <= split && a < b)
     432             {
     433                 a++;
     434             }
     435             temp = t[a];
     436             t[a] = t[b];
     437             t[b] = temp;
     438         }
     439         return a;
     440     }
     441 
     442     //get the index's number of t
     443     inline int GetNIndex(int t, int i)
     444     {
     445         return (t%(int)pow(10, i + 1) - t%(int)pow(10, i))/pow(10,i);
     446     }
     447 
     448     int* GetAllIndex(int t, int count)
     449     {
     450         int* array = new int[count];
     451         memset(array, 0, count*sizeof(int));
     452         int i = 0, sum = 0;
     453         while (t / pow(10, i) > 0)
     454         {
     455             int temp = t%pow(10, i + 1) - sum;
     456             sum += array[i];
     457             array[i] = temp / pow(10, i);
     458             i++;
     459         }
     460         return array;
     461     }
     462     
     463     void _RadixSort(T* t, int length = 0)
     464     {
     465         //对于多位数来说是count位数, 而对于扑克牌问题来说就是面值和花色了
     466         T max = t[0];
     467         for (int i = 0; i < length; i++)
     468         {
     469             if (max < t[i])
     470             {
     471                 max = t[i];
     472             }
     473         }
     474         int count = 0;
     475         //get the radix of max value;
     476         int k = max / pow(10, count);
     477         while (k != 0)
     478         {
     479             count++;
     480             k = max / pow(10, count);
     481         }
     482         //int* array = new int[length*(count-1)];
     483         //memset(array, 0, length*(count - 1)*sizeof(int));
     484 
     485         int* positionArray = new int[length];
     486         T* tempArray = new T[length];
     487         //*************************************************
     488         //change the codes more general for the problem of multi-decision sort
     489         //using counting sort to solve every single problem;
     490         for (int i = 0; i < count; i++)
     491         {
     492             int* countArray = new int[10];
     493             memset(countArray, 0, 10 * sizeof(10));
     494 
     495             for (int j = 0; j < length; j++)
     496             {
     497                 positionArray[j] = GetNIndex(t[j], i);
     498             }
     499             //the t is changing with positionArray;
     500             for (int m = 0; m < length; m++)
     501             {
     502                 countArray[positionArray[m]]++;
     503             }
     504             for (int m = 1; m < 10; m++)
     505             {
     506                 countArray[m] += countArray[m - 1];
     507                 countArray[m - 1]--;
     508             }
     509             countArray[9]--;
     510 
     511             for (int m = length - 1; m >= 0; m--)
     512             {
     513                 //无论其他怎么改变 位置都是相对的 positionArray[m]就是t[m]
     514                 tempArray[countArray[positionArray[m]]] = t[m];
     515                 countArray[positionArray[m]]--;
     516             }
     517             for (int m = 0; m < length; m++)
     518             {
     519                 t[m] = tempArray[m];
     520             }
     521             delete[] countArray;
     522         }
     523 
     524         delete[] positionArray;
     525         delete[] tempArray;
     526     }
     527 };
     528 
     529 #pragma region std::vector<T>
     530 template<typename T>
     531 class Sort<std::vector<T>>
     532 {
     533 public:
     534     typedef typename std::vector<T>::iterator iterator;
     535 public:
     536     //actually vector use the operator[] should be faster
     537     //the operator[] also used iterator
     538     void InsertSort(std::vector<T>& t)
     539     {
     540         if (t.size()>0)
     541         {
     542             for (std::vector<T>::iterator it = t.begin() + 1; it != t.end(); it++)
     543             {
     544                 std::vector<T>::iterator itFront = it - 1;
     545                 T temp = *(it);
     546 
     547                 while (*itFront > temp)
     548                 {
     549                     std::vector<T>::iterator itTemp = itFront;
     550                     itTemp++;
     551                     *itTemp = *itFront;
     552                     if (itFront != t.begin())
     553                     {
     554                         itFront--;
     555                         if (itFront == t.begin() && *itFront < temp)
     556                         {
     557                             itFront++;
     558                             break;
     559                         }
     560                     }
     561                     else
     562                     {
     563                         break;
     564                     }
     565                 }
     566                 *(itFront) = temp;
     567             }
     568         }
     569     }
     570 
     571     void MergeSort(std::vector<T>& t)
     572     {
     573         int length = t.size();
     574         if (length <= 1)
     575         {
     576             return;
     577         }
     578         else
     579         {
     580             _MergeSort(t, 0, length - 1);
     581         }
     582     }
     583 
     584     void HeapSort(std::vector<T>& t)
     585     {
     586         int length = t.size();
     587         try
     588         {
     589             if (length>0)
     590             {
     591                 length = length - 1;
     592                 BuildHeap(t, length);
     593                 for (int i = length; i >= 0; i--)
     594                 {
     595                     T temp = t[0];
     596                     t[0] = t[i];
     597                     t[i] = temp;
     598                     Max_Heapify(t, 0, i - 1);
     599                 }
     600             }
     601         }
     602         catch (std::out_of_range e)
     603         {
     604             std::cout << "out_of_range error" << std::endl;
     605         }
     606     }
     607 
     608     void QuickSort(std::vector<T>& t)
     609     {
     610         _QuickSort(t, 0, t.size() - 1);
     611     }
     612 
     613     void CountingSort(std::vector<T>&t)
     614     {
     615         if (typeid(T) == typeid(int))
     616         {
     617             int length = t.size();
     618             int count = 0;
     619             T* negetiveArray;
     620             T* positiveArray;
     621             //前一版本将比较的次数缩减到了3(n-2)/2次,但是行数太多
     622             for (int i = 0; i < length; i++)
     623             {
     624                 if (t[i] < 0)
     625                 {
     626                     count++;
     627                 }
     628             }
     629             negetiveArray = new T[count];
     630             positiveArray = new T[length - count];
     631             //split the array into the postive and negetive value arraies
     632             for (int i = 0, m = 0, n = 0; i < length; i++)
     633             {
     634                 if (t[i] < 0)
     635                 {
     636                     negetiveArray[m] = t[i];
     637                     m++;
     638                 }
     639                 else
     640                 {
     641                     positiveArray[n] = t[i];
     642                     n++;
     643                 }
     644             }
     645             T poMin = positiveArray[0], poMax = positiveArray[0];
     646             T neMin = negetiveArray[0], neMax = negetiveArray[0];
     647             for (int i = 0; i < count; i++)
     648             {
     649                 if (negetiveArray[i] < neMin)
     650                 {
     651                     neMin = negetiveArray[i];
     652                 }
     653                 if (negetiveArray[i] > neMax)
     654                 {
     655                     neMax = negetiveArray[i];
     656                 }
     657             }
     658             for (int i = 0; i < length - count; i++)
     659             {
     660                 if (positiveArray[i] < poMin)
     661                 {
     662                     poMin = positiveArray[i];
     663                 }
     664                 if (positiveArray[i] > poMax)
     665                 {
     666                     poMax = positiveArray[i];
     667                 }
     668             }
     669             //得到正负两个数组各自的最小最大差 并将两个数组映射到0-poMin;
     670             T poMinux = poMax - poMin;
     671             T neMinux = neMax - neMin;
     672 
     673             T* positiveArrayed = new T[length - count];
     674             int* countArray = new int[poMinux + 1];
     675             memset(countArray, 0, (poMinux + 1)*sizeof(T));
     676 
     677             for (int i = 0; i < length - count; i++)
     678             {
     679                 countArray[positiveArray[i] - poMin] ++;
     680                 //std::cout << countArray[i] << " ";
     681             }
     682             //此处与算法描述中不同的地方在于,countArray用于保存每个数存在的位置,但是该位置应该是从0开始的
     683             for (int i = 1; i <= poMinux; i++)
     684             {
     685                 //std::cout << countArray[i - 1] << " ";
     686                 countArray[i] = countArray[i] + countArray[i - 1];
     687                 countArray[i - 1]--;
     688             }
     689             countArray[poMinux]--;
     690             //将正数数组从后往前每一个数放到应该放的地方,之所以是从后往前是为了保持算法的稳定性
     691             for (int i = length - count - 1; i >= 0; i--)
     692             {
     693                 positiveArrayed[countArray[positiveArray[i] - poMin]] = positiveArray[i];
     694                 countArray[positiveArray[i] - poMin]--;
     695             }
     696 
     697             //负值数组开始的地方
     698             T* negetiveArrayed = new T[count];
     699             int* countArrayNe = new int[neMinux + 1];
     700             memset(countArrayNe, 0, (neMinux + 1)*sizeof(T));
     701 
     702             for (int i = 0; i < count; i++)
     703             {
     704                 countArrayNe[negetiveArray[i] - neMin]++;
     705             }
     706             for (int i = 1; i <= neMinux; i++)
     707             {
     708                 countArrayNe[i] += countArrayNe[i - 1];
     709                 countArrayNe[i - 1]--;
     710             }
     711             countArrayNe[neMinux]--;
     712 
     713             for (int i = count - 1; i >= 0; i--)
     714             {
     715                 negetiveArrayed[countArrayNe[negetiveArray[i] - neMin]] = negetiveArray[i];
     716                 countArrayNe[negetiveArray[i] - neMin]--;
     717             }
     718 
     719             //正负两个数组合并
     720             for (int i = 0, j = 0; i < length; i++)
     721             {
     722                 if (i < count)
     723                 {
     724                     t[i] = negetiveArrayed[i];
     725                 }
     726                 else
     727                 {
     728                     t[i] = positiveArrayed[j];
     729                     j++;
     730                 }
     731             }
     732 
     733             delete[] negetiveArray;
     734             delete[] positiveArray;
     735             delete[] countArray;
     736             delete[] countArrayNe;
     737             delete[] negetiveArrayed;
     738             delete[] positiveArrayed;
     739         }
     740         else
     741         {
     742             std::cout << "you are using non-vector<int> type";
     743         }
     744     }
     745 
     746     void RadixSort(std::vector<T>& t)
     747     {
     748         std::vector<T> positiveArray;
     749         std::vector<T> negetiveArray;
     750 
     751         for (iterator it = t.begin(); it != t.end(); it++)
     752         {
     753             if (*it < 0)
     754             {
     755                 negetiveArray.push_back(-*it);
     756             }
     757             else
     758             {
     759                 positiveArray.push_back(*it);
     760             }
     761         }
     762         _RadixSort(positiveArray);
     763         _RadixSort(negetiveArray);
     764         int i = 0;
     765         iterator itNe;
     766         if (negetiveArray.size() == 0)
     767         {
     768             itNe = negetiveArray.end();
     769         }
     770         else
     771         {
     772             itNe = --negetiveArray.end();
     773         }
     774         for (iterator it = t.begin(), itPo = positiveArray.begin(); it != t.end(); it++)
     775         {
     776             if (i < negetiveArray.size())
     777             {
     778                 *it = -*itNe;
     779                 i++;
     780                 if (itNe != negetiveArray.begin())
     781                 {
     782                     itNe--;
     783                 }
     784             }
     785             else
     786             {
     787                 *it = *itPo;
     788                 itPo++;
     789             }
     790         }
     791     }
     792 
     793     void BucketSort(std::vector<T>& t)
     794     {
     795         int length = t.size();
     796         T max = t[0], min = t[0];
     797         for (int i = 0; i < length; i++)
     798         {
     799             if (t[i]>max)
     800             {
     801                 max = t[i];
     802             }
     803             if (t[i] < min)
     804             {
     805                 min = t[i];
     806             }
     807         }
     808         int minux = max - min + 1;
     809         std::vector<T>* colArray = new std::vector<T>[length];
     810         for (iterator it = t.begin(); it != t.end(); it++)
     811         {
     812             int index = (*it - min)*length / minux;
     813             colArray[index].push_back(*it);
     814         }
     815         for (int i = 0; i < length; i++)
     816         {
     817             Sort<std::vector<T>>::InsertSort(colArray[i]);
     818         }
     819         for (int i = 0; i < length; i++)
     820         {
     821             for (iterator it = colArray[i].begin(); it != colArray[i].end(); it++)
     822             {
     823                 t[i] = *it;
     824             }
     825         }
     826         delete[] colArray;
     827     }
     828 
     829 private:
     830     void _MergeSort(std::vector<T>& t, int a, int b)
     831     {
     832         if (a<b)
     833         {
     834             int c = (a + b) / 2;
     835             _MergeSort(t, a, c);
     836             _MergeSort(t, c + 1, b);
     837             Merge(t, a, c, b);
     838         }
     839     }
     840 
     841     void Merge(std::vector<T>& t, int a, int c, int b)
     842     {
     843         //actually the operator[] is also using the iterator! which one is more effective?
     844         int n1 = c - a + 1;
     845         int n2 = b - c;
     846         //here to create the array dynamicly, remember to delete it;
     847         T* temp1 = new T[n1 + 1];
     848         T* temp2 = new T[n2 + 1];
     849 
     850         for (int i = 0; i<n1; i++)
     851         {
     852             temp1[i] = t[a + i];
     853         }
     854         //the biggest value of positive int
     855         temp1[n1] = 2147483647;
     856         for (int i = 0; i<n2; i++)
     857         {
     858             temp2[i] = t[c + 1 + i];
     859         }
     860         temp2[n2] = 2147483647;
     861 
     862         int m = 0, n = 0;
     863         for (int i = a; i <= b; i++)
     864         {
     865             if (temp1[m] <= temp2[n])
     866             {
     867                 t[i] = temp1[m];
     868                 m++;
     869             }
     870             else if (temp1[m]>temp2[n])
     871             {
     872                 t[i] = temp2[n];
     873                 n++;
     874             }
     875             else
     876             {
     877 
     878             }
     879         }
     880         //remember to clean it
     881         delete[] temp1;
     882         delete[] temp2;
     883     }
     884 
     885     int GetLeftChild(int i)
     886     {
     887         return (i + 1) << 1 - 1;
     888     }
     889 
     890     int GetRightChild(int i)
     891     {
     892         return (i + 1) << 1;
     893     }
     894 
     895     void Max_Heapify(std::vector<T>& t, int i, int length)
     896     {
     897         int  largest = 0;
     898         int l = GetLeftChild(i);
     899         int r = GetRightChild(i);
     900 
     901         if (l<=length && t[l]>t[i])
     902         {
     903             largest = l;
     904         }
     905         else
     906         {
     907             largest = i;
     908         }
     909 
     910 
     911         if (r<=length && t[r]>t[largest])
     912         {
     913             largest = r;
     914         }
     915 
     916         if (largest != i)
     917         {
     918             T temp = t[i];
     919             t[i] = t[largest];
     920             t[largest] = temp;
     921             Max_Heapify(t, largest, length);
     922         }
     923     }
     924 
     925     void BuildHeap(std::vector<T>& t, int length)
     926     {
     927         for (int i = length; i >= 0; i--)
     928         {
     929             Max_Heapify(t, i, length);
     930         }
     931     }
     932 
     933     void _QuickSort(std::vector<T>& t, int a, int b)
     934     {
     935         if (a < b)
     936         {
     937             int s = Partition(t, a, b);
     938             _QuickSort(t, a, s-1);
     939             _QuickSort(t, s + 1, b);
     940         }
     941     }
     942     
     943     int Partition(std::vector<T>& t, int a, int b)
     944     {
     945         T split = t[a];
     946         while (a < b)
     947         {
     948             while (t[b] >= split && a < b)
     949             {
     950                 b--;
     951             }
     952             T temp = t[a];
     953             t[a] = t[b];
     954             t[b] = temp;
     955             
     956             while (t[a] <= split && a < b)
     957             {
     958                 a++;
     959             }
     960             temp = t[a];
     961             t[a] = t[b];
     962             t[b] = temp;
     963         }
     964         return a;
     965     }
     966 
     967     inline int GetNIndex(int t, int i)
     968     {
     969         return (t % (int)pow(10, i + 1) - t % (int)pow(10, i)) / pow(10, i);
     970     }
     971 
     972     void _RadixSort(std::vector<T>& t)
     973     {
     974         //对于多位数来说是count位数, 而对于扑克牌问题来说就是面值和花色了
     975         T max = t[0];
     976         int length = t.size();
     977         for (int i = 0; i < length; i++)
     978         {
     979             if (max < t[i])
     980             {
     981                 max = t[i];
     982             }
     983         }
     984         int count = 0;
     985         //get the radix of max value;
     986         int k = max / pow(10, count);
     987         while (k != 0)
     988         {
     989             count++;
     990             k = max / pow(10, count);
     991         }
     992         //int* array = new int[length*(count-1)];
     993         //memset(array, 0, length*(count - 1)*sizeof(int));
     994 
     995         int* positionArray = new int[length];
     996         T* tempArray = new T[length];
     997         //*************************************************
     998         //change the codes more general for the problem of multi-decision sort
     999         for (int i = 0; i < count; i++)
    1000         {
    1001             int* countArray = new int[10];
    1002             memset(countArray, 0, 10 * sizeof(10));
    1003 
    1004             for (int j = 0; j < length; j++)
    1005             {
    1006                 positionArray[j] = GetNIndex(t[j], i);
    1007             }
    1008             //the t is changing with positionArray;
    1009             for (int m = 0; m < length; m++)
    1010             {
    1011                 countArray[positionArray[m]]++;
    1012             }
    1013             for (int m = 1; m < 10; m++)
    1014             {
    1015                 countArray[m] += countArray[m - 1];
    1016                 countArray[m - 1]--;
    1017             }
    1018             countArray[9]--;
    1019 
    1020             for (int m = length - 1; m >= 0; m--)
    1021             {
    1022                 //无论其他怎么改变 位置都是相对的 positionArray[m]就是t[m]
    1023                 tempArray[countArray[positionArray[m]]] = t[m];
    1024                 countArray[positionArray[m]]--;
    1025             }
    1026             for (int m = 0; m < length; m++)
    1027             {
    1028                 t[m] = tempArray[m];
    1029             }
    1030             delete[] countArray;
    1031         }
    1032 
    1033         delete[] positionArray;
    1034         delete[] tempArray;
    1035     }
    1036 
    1037 };
    1038 #pragma endregion
    1039 
    1040 #pragma region std::list<T>
    1041 template<typename T>
    1042 class Sort<std::list<T>>
    1043 {
    1044     //for the list, we can't directly use the operator+/-,because it is the list
    1045     //actually we can use the operator[] to change it, does list solved the problem?
    1046     //not effective at all
    1047     //we should support a method to increase or decrease the pointer(iterator)!
    1048     typedef typename std::list<T>::iterator iterator;
    1049 
    1050 public:
    1051     void InsertSort(std::list<T>& t)
    1052     {
    1053         for (std::list<T>::iterator it = t.begin(); it != t.end(); it++)
    1054         {
    1055             std::list<T>::iterator itFront = it;
    1056             if (++it == t.end())
    1057             {
    1058                 break;
    1059             }
    1060             T temp = *it;
    1061             it--;
    1062 
    1063             while (*itFront > temp)
    1064             {
    1065                 std::list<T>::iterator itTemp = itFront;
    1066                 itTemp++;
    1067                 *itTemp = *itFront;
    1068                 if (itFront != t.begin())
    1069                 {
    1070                     itFront--;
    1071                     if (itFront == t.begin() && *itFront < temp)
    1072                     {
    1073                         itFront++;
    1074                         break;
    1075                     }
    1076                 }
    1077                 else
    1078                 {
    1079                     break;
    1080                 }
    1081             }
    1082             *itFront = temp;
    1083         }
    1084     }
    1085 
    1086     void MergeSort(std::list<T>& t)
    1087     {
    1088         int length = t.size();
    1089         _MergeSort(t, 0, length - 1);
    1090     }
    1091      
    1092     void HeapSort(std::list<T>& t)
    1093     {
    1094         //the worst palce is to find the son of iterator, it will cost too much;
    1095         int length = t.size() - 1;
    1096         BuildHeap(t);
    1097         iterator begin = t.begin();
    1098         iterator end = t.end();
    1099         end--;
    1100         for (int i = length; i >= 1; i--)
    1101         {
    1102             T temp = *end;
    1103             *end = *begin;
    1104             *begin = temp;
    1105             MaxHeapify(t, begin, i - 1);
    1106             end--;
    1107         }
    1108 
    1109     }
    1110 
    1111     void QuickSort(std::list<T>& t)
    1112     {
    1113         _QuickSort(t, 0, t.size() - 1);
    1114     }
    1115 
    1116     void CountingSort(std::list<T>& t)
    1117     {
    1118         //偷天换日一回,将iterator操作变换成数组操作
    1119         if (typeid(T) == typeid(int))
    1120         {
    1121             int length = t.size();
    1122             int count = 0;
    1123             T* positiveArray;
    1124             T* negetiveArray;
    1125 
    1126             iterator it;
    1127             for (it = t.begin(); it != t.end(); it++)
    1128             {
    1129                 if (*it < 0)
    1130                 {
    1131                     count++;
    1132                 }
    1133             }
    1134             positiveArray = new T[length-count];
    1135             negetiveArray = new T[count];
    1136             int m = 0, n = 0;
    1137             for (it = t.begin(); it != t.end(); it++)
    1138             {
    1139                 if (*it < 0)
    1140                 {
    1141                     negetiveArray[m] = *it;
    1142                     m++;
    1143                 }
    1144                 else
    1145                 {
    1146                     positiveArray[n] = *it;
    1147                     n++;
    1148                 }
    1149             }
    1150 
    1151             T poMin = positiveArray[0], poMax = positiveArray[0];
    1152             T neMin = negetiveArray[0], neMax = negetiveArray[0];
    1153             
    1154             for (int i = 0; i < length - count; i++)
    1155             {
    1156                 if (positiveArray[i]>poMax)
    1157                 {
    1158                     poMax = positiveArray[i];
    1159                 }
    1160                 if (positiveArray[i] < poMin)
    1161                 {
    1162                     poMin = positiveArray[i];
    1163                 }
    1164             }
    1165             for (int i = 0; i <count; i++)
    1166             {
    1167                 if (negetiveArray[i]>neMax)
    1168                 {
    1169                     neMax = negetiveArray[i];
    1170                 }
    1171                 if (negetiveArray[i] < neMin)
    1172                 {
    1173                     neMin = negetiveArray[i];
    1174                 }
    1175             }
    1176             T poMinux = poMax - poMin;
    1177             T neMinux = neMax - neMin;
    1178 
    1179             //positive array
    1180             T* positiveArrayed = new T[length - count];
    1181             T* countArrayPo = new T[poMinux + 1];
    1182             memset(countArrayPo, 0, (poMinux + 1)*sizeof(T));
    1183 
    1184             for (int i = 0; i < length - count; i++)
    1185             {
    1186                 countArrayPo[positiveArray[i]-poMin]++;
    1187             }
    1188             for (int i = 1; i <= poMinux; i++)
    1189             {
    1190                 countArrayPo[i] += countArrayPo[i - 1];
    1191                 countArrayPo[i - 1]--;
    1192             }
    1193             countArrayPo[poMinux]--;
    1194             for (int i = length - count - 1; i >= 0; i--)
    1195             {
    1196                 positiveArrayed[countArrayPo[positiveArray[i] - poMin]] = positiveArray[i];
    1197                 countArrayPo[positiveArray[i] - poMin]--;
    1198             }
    1199             //negetive value
    1200             T* negetiveArrayed = new T[count];
    1201             T* countArrayNe = new T[neMinux + 1];
    1202             memset(countArrayNe, 0, (neMinux + 1)*sizeof(T));
    1203             for (int i = 0; i < count; i++)
    1204             {
    1205                 countArrayNe[negetiveArray[i] - neMin]++;
    1206             }
    1207             for (int i = 1; i <= neMinux; i++)
    1208             {
    1209                 countArrayNe[i] += countArrayNe[i - 1];
    1210                 countArrayNe[i]--;
    1211             }
    1212             countArrayNe[neMinux]--;
    1213             for (int i = count - 1; i >= 0; i--)
    1214             {
    1215                 negetiveArrayed[countArrayNe[negetiveArray[i] - neMin]] = negetiveArray[i];
    1216                 countArrayNe[negetiveArray[i] - neMin]--;
    1217             }
    1218             //gather two arraies
    1219             m = 0, n = 0;
    1220             for (it = t.begin(); it != t.end(); it++)
    1221             {
    1222                 if (m < count)
    1223                 {
    1224                     *it = negetiveArrayed[m];
    1225                     m++;
    1226                 }
    1227                 else
    1228                 {
    1229                     *it = positiveArrayed[n];
    1230                     n++;
    1231                 }
    1232 
    1233             }
    1234 
    1235             delete[] positiveArray;
    1236             delete[] negetiveArray;
    1237             delete[] countArrayPo;
    1238             delete[] countArrayNe;
    1239             delete[] positiveArrayed;
    1240             delete[] negetiveArrayed;
    1241         }
    1242         else
    1243         {
    1244             std::cout << "you are using non-list<int> type
    ";
    1245         }
    1246     }
    1247 
    1248     void RadixSort(std::list<T>& t)
    1249     {
    1250         std::list<T> positiveArray;
    1251         std::list<T> negetiveArray;
    1252 
    1253         for (iterator it = t.begin(); it != t.end(); it++)
    1254         {
    1255             if (*it < 0)
    1256             {
    1257                 negetiveArray.push_back(-*it);
    1258             }
    1259             else
    1260             {
    1261                 positiveArray.push_back(*it);
    1262             }
    1263         }
    1264         _RadixSort(positiveArray);
    1265         _RadixSort(negetiveArray);
    1266         int i = 0;
    1267         iterator itNe;
    1268         if (negetiveArray.size() == 0)
    1269         {
    1270             itNe = negetiveArray.end();
    1271         }
    1272         else
    1273         {
    1274             itNe = --negetiveArray.end();
    1275         }
    1276         for (iterator it = t.begin(), itPo = positiveArray.begin(); it != t.end(); it++)
    1277         {
    1278             if (i < negetiveArray.size())
    1279             {
    1280                 *it = -*itNe;
    1281                 i++;
    1282                 if (itNe != negetiveArray.begin())
    1283                 {
    1284                     itNe--;
    1285                 }
    1286             }
    1287             else
    1288             {
    1289                 *it = *itPo;
    1290                 itPo++;
    1291             }
    1292         }
    1293     }
    1294 
    1295     void BucketSort(std::list<T>& t)
    1296     {
    1297         int length = t.size();
    1298         T max = *(t.begin()), min = *(t.begin());
    1299         for (iterator it = t.begin(); it != t.end(); it++)
    1300         {
    1301             if (*it > max)
    1302             {
    1303                 max = *it;
    1304             }
    1305             if (*it < min)
    1306             {
    1307                 min = *it;
    1308             }
    1309         }
    1310         int minux = max - min+1;
    1311         std::vector<T>* colArray = new std::vector<T>[length];
    1312         for (iterator it = t.begin(); it != t.end(); it++)
    1313         {
    1314             int index = (*it - min)*length / minux;
    1315             colArray[index].push_back(*it);
    1316         }
    1317         for (int i = 0; i < length; i++)
    1318         {
    1319             Sort<std::vector<T>> s;
    1320             s.InsertSort(colArray[i]);
    1321         }
    1322         int m = 0;
    1323         //the border condition annoys me a lot!
    1324         for (iterator it = t.begin(); it != t.end(); m++)
    1325         {
    1326             for (std::vector<T>::iterator itCol = colArray[m].begin(); itCol != colArray[m].end(); itCol++)
    1327             {
    1328                 *it = *itCol;
    1329                 it++;
    1330             }
    1331         }
    1332     }
    1333 
    1334 private:
    1335     void _MergeSort(std::list<T>& t, int a, int b)
    1336     {
    1337         if (a<b)
    1338         {
    1339             int c = (a + b) / 2;
    1340             _MergeSort(t, a, c);
    1341             _MergeSort(t, c + 1, b);
    1342 
    1343             std::list<T>::iterator ita = t.begin();
    1344             std::list<T>::iterator itc = t.begin();
    1345             std::list<T>::iterator itb = t.begin();
    1346             for (int i = 0; i <= b; i++)
    1347             {
    1348                 if (i<a)
    1349                 {
    1350                     ita++;
    1351                 }
    1352                 if (i<c)
    1353                 {
    1354                     itc++;
    1355                 }
    1356                 if (i<b)
    1357                 {
    1358                     itb++;
    1359                 }
    1360             }
    1361             Merge(t, ita, itc, itb);
    1362         }
    1363 
    1364     }
    1365 
    1366     //Here we can't directly use the std::list<T>::iterator, use the typedef to replace it
    1367     //compiler of ms
    1368     void  Merge(std::list<T>& t, iterator a, iterator c, iterator b)
    1369     {
    1370         std::list<T> temp1;
    1371         std::list<T>::iterator nothing = ++c;
    1372         c--;
    1373         for (std::list<T>::iterator it = a; it != nothing; it++)
    1374         {
    1375             temp1.push_back(*it);
    1376         }
    1377         temp1.push_back(2147483647);
    1378         std::list<T> temp2;
    1379         std::list<T>::iterator something = ++b;
    1380         b--;
    1381         for (std::list<T>::iterator it = nothing; it != something; it++)
    1382         {
    1383             temp2.push_back(*it);
    1384         }
    1385         temp2.push_back(2147483647);
    1386 
    1387 
    1388         std::list<T>::iterator itTemp1 = temp1.begin();
    1389         std::list<T>::iterator itTemp2 = temp2.begin();
    1390         for (std::list<T>::iterator it = a; it != something; it++)
    1391         {
    1392             if (*itTemp1 > *itTemp2)
    1393             {
    1394                 *it = *itTemp2;
    1395                 itTemp2++;
    1396             }
    1397             else
    1398             {
    1399                 *it = *itTemp1;
    1400                 itTemp1++;
    1401             }
    1402         }
    1403     }
    1404 
    1405     iterator IteratorIncrease(std::list<T>& t, iterator it,int i)
    1406     {
    1407         iterator tempIt = it;
    1408         for (int index = 0; index < i; index++)
    1409         {
    1410             if (tempIt == t.end()--)
    1411             {
    1412                 return t.end();
    1413             }
    1414             tempIt++;
    1415         }
    1416         return tempIt;
    1417     }
    1418 
    1419     iterator IteratorDecrese(std::list<T>& t, iterator it, int i)
    1420     {
    1421         iterator tempIt = it;
    1422         for (int index = 0; index < i; i++)
    1423         {
    1424             if (tempIt == t.begin())
    1425             {
    1426                 std::cout << "out of range with iterator in decrese";
    1427                 return t.end();
    1428             }
    1429             else
    1430             {
    1431                 tempIt--;
    1432             }
    1433         }
    1434         return tempIt;
    1435     }
    1436 
    1437     int GetIteratorPosition(std::list<T>& t, iterator it)
    1438     {
    1439         int position = -1;
    1440         iterator tempIt = t.begin();
    1441         for (tempIt; tempIt != t.end(); tempIt++)
    1442         {
    1443             position++;
    1444             if (tempIt == it)
    1445             {
    1446                 break;
    1447             }
    1448         }
    1449         if (position >= t.size())
    1450         {
    1451             return -1;
    1452         }
    1453         return position;
    1454     }
    1455 
    1456     int GetLeftChild(std::list<T>& t, iterator it)
    1457     {
    1458         int number = -1;
    1459         iterator tempIt;
    1460         for (tempIt = t.begin(); tempIt != t.end(); tempIt++)
    1461         {
    1462             number++;
    1463             if (tempIt == it)
    1464             {
    1465                 break;
    1466             }
    1467         }
    1468         if (number >= t.size())
    1469         {
    1470             //the it is not one of the t'iterator;
    1471             return NULL;
    1472         }
    1473 
    1474         int leftChild = ((number + 1) << 1) - 1;
    1475         return leftChild;
    1476     }
    1477 
    1478     int GetRightChild(std::list<T>& t, iterator it)
    1479     {
    1480         int number = -1;
    1481         iterator tempIt;
    1482         for (tempIt = t.begin(); tempIt != t.end(); tempIt++)
    1483         {
    1484             number++;
    1485             if (tempIt == it)
    1486             {
    1487                 break;
    1488             }
    1489         }
    1490         if (number >= t.size())
    1491         {
    1492             //the it is not one of the t'iterator;
    1493             return NULL;
    1494         }
    1495 
    1496         int RightChild = (number + 1) << 1;
    1497         return RightChild;
    1498     }
    1499 
    1500     void MaxHeapify(std::list<T>& t, iterator it, int length)
    1501     {
    1502         //iterator tempIt = IteratorIncrease(t, t.begin(), length);
    1503         int leftChild = GetLeftChild(t, it);
    1504         int rightChild = GetRightChild(t, it);
    1505         int i = GetIteratorPosition(t, it);
    1506 
    1507         iterator itLeft = IteratorIncrease(t, t.begin(), leftChild);
    1508         iterator itRight = IteratorIncrease(t, t.begin(), rightChild);
    1509         
    1510         int largest = 0;
    1511         T tLargest;
    1512         if (leftChild <= length && *itLeft > *it)
    1513         {
    1514             largest = leftChild;
    1515             tLargest = *itLeft;
    1516         }
    1517         else
    1518         {
    1519             largest = i;
    1520             tLargest = *it;
    1521         }
    1522 
    1523         if (rightChild <= length  && *itRight > tLargest)
    1524         {
    1525             largest = rightChild;
    1526             tLargest = *itRight;
    1527         }
    1528 
    1529         if (largest != i)
    1530         {
    1531             T temp = *it;
    1532             *it = tLargest;
    1533 
    1534             if (largest == leftChild)
    1535             {
    1536                 *itLeft = temp;
    1537                 MaxHeapify(t, itLeft, length);
    1538             }
    1539             else
    1540             {
    1541                 *itRight = temp;
    1542                 MaxHeapify(t, itRight, length);
    1543             }
    1544         }
    1545     }
    1546 
    1547     void BuildHeap(std::list<T>& t)
    1548     {
    1549         for (int i = (t.size() - 1) / 2; i >= 0; i--)
    1550         {
    1551             iterator temp = IteratorIncrease(t, t.begin(), i);
    1552             MaxHeapify(t, temp, t.size()-1);
    1553         }
    1554     }
    1555 
    1556     void _QuickSort(std::list<T>& t, int a, int b)
    1557     {
    1558         if (a < b)
    1559         {
    1560             int s = Partition(t, a, b);
    1561             _QuickSort(t, a, s - 1);
    1562             _QuickSort(t, s + 1, b);
    1563         }
    1564     }
    1565 
    1566     int Partition(std::list<T>& t, int a, int b)
    1567     {
    1568         iterator l = IteratorIncrease(t, t.begin(), a);
    1569         iterator r = IteratorIncrease(t, t.begin(), b);
    1570 
    1571         T split = *l;
    1572         while (a < b && l != t.end() && r != t.end())
    1573         {
    1574             while (a<b && *r>split)
    1575             {
    1576                 b--;
    1577                 r--;
    1578             }
    1579             T temp = *r;
    1580             *r = *l;
    1581             *l = temp;
    1582 
    1583             while (a<b && *l < split)
    1584             {
    1585                 a++;
    1586                 l++;
    1587             }
    1588             temp = *l;
    1589             *l = *r;
    1590             *r = temp;
    1591         }
    1592         return a;
    1593     }
    1594     
    1595     inline int GetNIndex(int t, int i)
    1596     {
    1597         return (t % (int)pow(10, i + 1) - t % (int)pow(10, i)) / pow(10, i);
    1598     }
    1599 
    1600     void _RadixSort(std::list<T>& t)
    1601     {
    1602         int length = t.size();
    1603         if (length == 0)
    1604         {
    1605             return;
    1606         }
    1607         T max = *t.begin();
    1608         int count = 0;
    1609         for (iterator it = t.begin(); it != t.end(); it++)
    1610         {
    1611             if (*it > max)
    1612             {
    1613                 max = *it;
    1614             }
    1615         }
    1616         int k = max / pow(10, count);
    1617         while (k != 0)
    1618         {
    1619             count++;
    1620             k = max / pow(10, count);
    1621         }
    1622 
    1623         T* tempArray = new int[length];
    1624         for (int i = 0; i < count; i++)
    1625         {
    1626             int* positionArray = new int[length];
    1627             int* countArray = new int[10];
    1628             memset(countArray, 0, 10 * sizeof(int));
    1629 
    1630             iterator it = t.begin();
    1631             for (int j = 0; j < length; j++)
    1632             {
    1633                 positionArray[j] = GetNIndex(*it, i);
    1634                 it++;
    1635             }
    1636 
    1637             for (int m = 0; m < length; m++)
    1638             {
    1639                 countArray[positionArray[m]]++;
    1640             }
    1641             for (int m = 1; m < 10; m++)
    1642             {
    1643                 countArray[m] += countArray[m - 1];
    1644                 countArray[m - 1]--;
    1645             }
    1646             countArray[9]--;
    1647             //
    1648             it = --t.end();
    1649             for (int m = length - 1; m >= 0; m--)
    1650             {
    1651                 tempArray[countArray[positionArray[m]]] = *it;
    1652                 countArray[positionArray[m]]--;
    1653                 if (it != t.begin())
    1654                 {
    1655                     it--;
    1656                 }
    1657             }
    1658             int m = 0;
    1659             for (it = t.begin(); it != t.end(); it++)
    1660             {
    1661                 *it = tempArray[m];
    1662                 m++;
    1663             }
    1664             delete[] positionArray;
    1665             delete[] countArray;
    1666         }
    1667         delete[] tempArray;
    1668     }
    1669 };
    1670 
    1671 #pragma endregion

       过段时间再贴上树这种树(非二叉树)结构的模板,其格式也会向标准模板靠齐,基本功能已经具有,但是还不够强大,远没有达到通用的标准。其存储结构是孩子兄弟存储法,针对树的前序遍历已经写好。

  • 相关阅读:
    windows的80端口被占用时的处理方法
    Ansible自动化运维工具安装与使用实例
    Tomcat的测试网页换成自己项目首页
    LeetCode 219. Contains Duplicate II
    LeetCode Contest 177
    LeetCode 217. Contains Duplicate
    LeetCode 216. Combination Sum III(DFS)
    LeetCode 215. Kth Largest Element in an Array(排序)
    Contest 176 LeetCode 1354. Construct Target Array With Multiple Sums(优先队列,递推)
    Contest 176
  • 原文地址:https://www.cnblogs.com/beneathginkgo/p/4589136.html
Copyright © 2011-2022 走看看