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

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

posted @ 2015-06-19 22:51  银杏花下  阅读(1241)  评论(2编辑  收藏  举报