• 模板化的七种排序算法,适用于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

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

  • 相关阅读:
    yk20192320
    JS常用方法 限制用户输入的方法
    话说最强悍的团队,博客园团队!
    输入框打开禁用自动填充功能
    老生常谈:Asp.net MVC 3+ Jquery UI Autocomplete实现百度效果
    节日logo
    第一篇:Asp.net MVP模式介绍
    VBS 类
    《JavaScript编程精解》简明读书心得上
    Three.js源码阅读笔记1
  • 原文地址:https://www.cnblogs.com/beneathginkgo/p/4589136.html
Copyright © 2020-2023  润新知