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

  一共写了七种排序,插入排序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 = )
  12. {
  13. }
  14.  
  15. //the hardest part is to judge the correctness
  16. void MergeSort(T* t, int length = )
  17. {
  18. }
  19.  
  20. void HeapSort(T* t, int length = )
  21. {
  22. }
  23.  
  24. void QuickSort(T* t, int length = )
  25. {
  26. }
  27.  
  28. void CountingSort(T* t, int length = )
  29. {
  30. }
  31.  
  32. void RadixSort(T* t, int length = )
  33. {
  34. }
  35.  
  36. void BucketSort(T* t, int length = )
  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 = )
  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 = ; i<length; i++)
  28. {
  29. T temp = t[i];
  30. int j = i - ;
  31. while (j >= && t[j]>temp)
  32. {
  33. t[j + ] = t[j];
  34. --j;
  35. }
  36. t[j + ] = 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()>)
  54. {
  55. for (std::vector<T>::iterator it = t.begin() + ; it != t.end(); it++)
  56. {
  57. std::vector<T>::iterator itFront = it - ;
  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 = )
  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 = ; i<length; i++)
  28. {
  29. T temp = t[i];
  30. int j = i - ;
  31. while (j >= && t[j]>temp)
  32. {
  33. t[j + ] = t[j];
  34. --j;
  35. }
  36. t[j + ] = temp;
  37. }
  38. }
  39. }
  40.  
  41. //the hardest part is to judge the correctness
  42. void MergeSort(T* t, int length = )
  43. {
  44. _MergeSort(t, , length - );
  45. }
  46.  
  47. void HeapSort(T* t, int length = )
  48. {
  49. try
  50. {
  51. if (length>)
  52. {
  53. length = length - ;
  54. BuildHeap(t, length);
  55. for (int i = length; i >= ; i--)
  56. {
  57. T temp = t[];
  58. t[] = t[i];
  59. t[i] = temp;
  60. Max_Heapify(t, , i - );
  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 = )
  71. {
  72. _QuickSort(t, , length-);
  73. }
  74.  
  75. //this one can only work in integer, negetive value is also included
  76. void CountingSort(T* t, int length = )
  77. {
  78. if (typeid(T) == typeid(int))
  79. {
  80. //one iterator to check the min, max, the number of negetive value
  81. int count = ;
  82. T* negetiveArray;
  83. T* positiveArray;
  84. //前一版本将比较的次数缩减到了3(n-2)/2次,但是行数太多
  85. for (int i = ; i < length; i++)
  86. {
  87. if (t[i] < )
  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 = , m = , n = ; i < length; i++)
  96. {
  97. if (t[i] < )
  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[], poMax = positiveArray[];
  109. T neMin = negetiveArray[], neMax = negetiveArray[];
  110. for (int i = ; 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 = ; 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 + ];
  138. memset(countArray, , (poMinux + )*sizeof(T));
  139.  
  140. for (int i = ; i < length - count; i++)
  141. {
  142. countArray[positiveArray[i] - poMin] ++;
  143. //std::cout << countArray[i] << " ";
  144. }
  145. //此处与算法描述中不同的地方在于,countArray用于保存每个数存在的位置,但是该位置应该是从0开始的
  146. for (int i = ; i <= poMinux; i++)
  147. {
  148. //std::cout << countArray[i - 1] << " ";
  149. countArray[i] = countArray[i] + countArray[i - ];
  150. countArray[i - ]--;
  151. }
  152. countArray[poMinux]--;
  153. //将正数数组从后往前每一个数放到应该放的地方,之所以是从后往前是为了保持算法的稳定性
  154. for (int i = length - count - ; i >= ; 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 + ];
  163. memset(countArrayNe, , (neMinux + )*sizeof(T));
  164.  
  165. for (int i = ; i < count; i++)
  166. {
  167. countArrayNe[negetiveArray[i] - neMin]++;
  168. }
  169. for (int i = ; i <= neMinux; i++)
  170. {
  171. countArrayNe[i] += countArrayNe[i - ];
  172. countArrayNe[i - ]--;
  173. }
  174. countArrayNe[neMinux]--;
  175.  
  176. for (int i = count - ; i >= ; i--)
  177. {
  178. negetiveArrayed[countArrayNe[negetiveArray[i] - neMin]] = negetiveArray[i];
  179. countArrayNe[negetiveArray[i] - neMin]--;
  180. }
  181.  
  182. //正负两个数组合并
  183. for (int i = , j = ; 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 = )
  210. {
  211. int count = ;
  212. for (int i = ; i < length; i++)
  213. {
  214. if (t[i] < )
  215. {
  216. count++;
  217. }
  218. }
  219. T* positiveArray = new T[length - count];
  220. T* negetiveArray = new T[count];
  221.  
  222. for (int i = , m=, n=; i < length; i++)
  223. {
  224. if (t[i] < )
  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 = , m=count-, n =; 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 = )
  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[], min = t[];
  267. for (int i = ; 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 +;
  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 = ; 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 = ; i < length; i++)
  289. {
  290. std::vector<T>& rawArray = colArray[i];
  291. Sort<std::vector<T>>::InsertSort(rawArray);
  292. }
  293. for (int i = , index=; 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) / ;
  312. _MergeSort(t, a, c);
  313. _MergeSort(t, c + , 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 + ;
  321. int n2 = b - c;
  322. //here to create the array dynamicly, remember to delete it;
  323. T* temp1 = new T[n1 + ];
  324. T* temp2 = new T[n2 + ];
  325.  
  326. for (int i = ; i<n1; i++)
  327. {
  328. temp1[i] = t[a + i];
  329. }
  330. //the biggest value of positive int
  331. temp1[n1] = ;
  332. for (int i = ; i<n2; i++)
  333. {
  334. temp2[i] = t[c + + i];
  335. }
  336. temp2[n2] = ;
  337.  
  338. int m = , n = ;
  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 = ;
  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 + ) << ) - ;
  391. }
  392.  
  393. inline int GetRightChild(int i)
  394. {
  395. return (i + ) << ;
  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 / ; i >= ; 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-);
  413. _QuickSort(t, s + , 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(, i + ) - t%(int)pow(, i))/pow(,i);
  446. }
  447.  
  448. int* GetAllIndex(int t, int count)
  449. {
  450. int* array = new int[count];
  451. memset(array, , count*sizeof(int));
  452. int i = , sum = ;
  453. while (t / pow(, i) > )
  454. {
  455. int temp = t%pow(, i + ) - sum;
  456. sum += array[i];
  457. array[i] = temp / pow(, i);
  458. i++;
  459. }
  460. return array;
  461. }
  462.  
  463. void _RadixSort(T* t, int length = )
  464. {
  465. //对于多位数来说是count位数, 而对于扑克牌问题来说就是面值和花色了
  466. T max = t[];
  467. for (int i = ; i < length; i++)
  468. {
  469. if (max < t[i])
  470. {
  471. max = t[i];
  472. }
  473. }
  474. int count = ;
  475. //get the radix of max value;
  476. int k = max / pow(, count);
  477. while (k != )
  478. {
  479. count++;
  480. k = max / pow(, 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 = ; i < count; i++)
  491. {
  492. int* countArray = new int[];
  493. memset(countArray, , * sizeof());
  494.  
  495. for (int j = ; j < length; j++)
  496. {
  497. positionArray[j] = GetNIndex(t[j], i);
  498. }
  499. //the t is changing with positionArray;
  500. for (int m = ; m < length; m++)
  501. {
  502. countArray[positionArray[m]]++;
  503. }
  504. for (int m = ; m < ; m++)
  505. {
  506. countArray[m] += countArray[m - ];
  507. countArray[m - ]--;
  508. }
  509. countArray[]--;
  510.  
  511. for (int m = length - ; m >= ; m--)
  512. {
  513. //无论其他怎么改变 位置都是相对的 positionArray[m]就是t[m]
  514. tempArray[countArray[positionArray[m]]] = t[m];
  515. countArray[positionArray[m]]--;
  516. }
  517. for (int m = ; 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()>)
  541. {
  542. for (std::vector<T>::iterator it = t.begin() + ; it != t.end(); it++)
  543. {
  544. std::vector<T>::iterator itFront = it - ;
  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 <= )
  575. {
  576. return;
  577. }
  578. else
  579. {
  580. _MergeSort(t, , length - );
  581. }
  582. }
  583.  
  584. void HeapSort(std::vector<T>& t)
  585. {
  586. int length = t.size();
  587. try
  588. {
  589. if (length>)
  590. {
  591. length = length - ;
  592. BuildHeap(t, length);
  593. for (int i = length; i >= ; i--)
  594. {
  595. T temp = t[];
  596. t[] = t[i];
  597. t[i] = temp;
  598. Max_Heapify(t, , i - );
  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, , t.size() - );
  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 = ;
  619. T* negetiveArray;
  620. T* positiveArray;
  621. //前一版本将比较的次数缩减到了3(n-2)/2次,但是行数太多
  622. for (int i = ; i < length; i++)
  623. {
  624. if (t[i] < )
  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 = , m = , n = ; i < length; i++)
  633. {
  634. if (t[i] < )
  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[], poMax = positiveArray[];
  646. T neMin = negetiveArray[], neMax = negetiveArray[];
  647. for (int i = ; 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 = ; 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 + ];
  675. memset(countArray, , (poMinux + )*sizeof(T));
  676.  
  677. for (int i = ; i < length - count; i++)
  678. {
  679. countArray[positiveArray[i] - poMin] ++;
  680. //std::cout << countArray[i] << " ";
  681. }
  682. //此处与算法描述中不同的地方在于,countArray用于保存每个数存在的位置,但是该位置应该是从0开始的
  683. for (int i = ; i <= poMinux; i++)
  684. {
  685. //std::cout << countArray[i - 1] << " ";
  686. countArray[i] = countArray[i] + countArray[i - ];
  687. countArray[i - ]--;
  688. }
  689. countArray[poMinux]--;
  690. //将正数数组从后往前每一个数放到应该放的地方,之所以是从后往前是为了保持算法的稳定性
  691. for (int i = length - count - ; i >= ; 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 + ];
  700. memset(countArrayNe, , (neMinux + )*sizeof(T));
  701.  
  702. for (int i = ; i < count; i++)
  703. {
  704. countArrayNe[negetiveArray[i] - neMin]++;
  705. }
  706. for (int i = ; i <= neMinux; i++)
  707. {
  708. countArrayNe[i] += countArrayNe[i - ];
  709. countArrayNe[i - ]--;
  710. }
  711. countArrayNe[neMinux]--;
  712.  
  713. for (int i = count - ; i >= ; i--)
  714. {
  715. negetiveArrayed[countArrayNe[negetiveArray[i] - neMin]] = negetiveArray[i];
  716. countArrayNe[negetiveArray[i] - neMin]--;
  717. }
  718.  
  719. //正负两个数组合并
  720. for (int i = , j = ; 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 < )
  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 = ;
  765. iterator itNe;
  766. if (negetiveArray.size() == )
  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[], min = t[];
  797. for (int i = ; 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 + ;
  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 = ; i < length; i++)
  816. {
  817. Sort<std::vector<T>>::InsertSort(colArray[i]);
  818. }
  819. for (int i = ; 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) / ;
  835. _MergeSort(t, a, c);
  836. _MergeSort(t, c + , 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 + ;
  845. int n2 = b - c;
  846. //here to create the array dynamicly, remember to delete it;
  847. T* temp1 = new T[n1 + ];
  848. T* temp2 = new T[n2 + ];
  849.  
  850. for (int i = ; i<n1; i++)
  851. {
  852. temp1[i] = t[a + i];
  853. }
  854. //the biggest value of positive int
  855. temp1[n1] = ;
  856. for (int i = ; i<n2; i++)
  857. {
  858. temp2[i] = t[c + + i];
  859. }
  860. temp2[n2] = ;
  861.  
  862. int m = , n = ;
  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 + ) << - ;
  888. }
  889.  
  890. int GetRightChild(int i)
  891. {
  892. return (i + ) << ;
  893. }
  894.  
  895. void Max_Heapify(std::vector<T>& t, int i, int length)
  896. {
  897. int largest = ;
  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. if (r<=length && t[r]>t[largest])
  911. {
  912. largest = r;
  913. }
  914.  
  915. if (largest != i)
  916. {
  917. T temp = t[i];
  918. t[i] = t[largest];
  919. t[largest] = temp;
  920. Max_Heapify(t, largest, length);
  921. }
  922. }
  923.  
  924. void BuildHeap(std::vector<T>& t, int length)
  925. {
  926. for (int i = length; i >= ; i--)
  927. {
  928. Max_Heapify(t, i, length);
  929. }
  930. }
  931.  
  932. void _QuickSort(std::vector<T>& t, int a, int b)
  933. {
  934. if (a < b)
  935. {
  936. int s = Partition(t, a, b);
  937. _QuickSort(t, a, s-);
  938. _QuickSort(t, s + , b);
  939. }
  940. }
  941.  
  942. int Partition(std::vector<T>& t, int a, int b)
  943. {
  944. T split = t[a];
  945. while (a < b)
  946. {
  947. while (t[b] >= split && a < b)
  948. {
  949. b--;
  950. }
  951. T temp = t[a];
  952. t[a] = t[b];
  953. t[b] = temp;
  954.  
  955. while (t[a] <= split && a < b)
  956. {
  957. a++;
  958. }
  959. temp = t[a];
  960. t[a] = t[b];
  961. t[b] = temp;
  962. }
  963. return a;
  964. }
  965.  
  966. inline int GetNIndex(int t, int i)
  967. {
  968. return (t % (int)pow(, i + ) - t % (int)pow(, i)) / pow(, i);
  969. }
  970.  
  971. void _RadixSort(std::vector<T>& t)
  972. {
  973. //对于多位数来说是count位数, 而对于扑克牌问题来说就是面值和花色了
  974. T max = t[];
  975. int length = t.size();
  976. for (int i = ; i < length; i++)
  977. {
  978. if (max < t[i])
  979. {
  980. max = t[i];
  981. }
  982. }
  983. int count = ;
  984. //get the radix of max value;
  985. int k = max / pow(, count);
  986. while (k != )
  987. {
  988. count++;
  989. k = max / pow(, count);
  990. }
  991. //int* array = new int[length*(count-1)];
  992. //memset(array, 0, length*(count - 1)*sizeof(int));
  993.  
  994. int* positionArray = new int[length];
  995. T* tempArray = new T[length];
  996. //*************************************************
  997. //change the codes more general for the problem of multi-decision sort
  998. for (int i = ; i < count; i++)
  999. {
  1000. int* countArray = new int[];
  1001. memset(countArray, , * sizeof());
  1002.  
  1003. for (int j = ; j < length; j++)
  1004. {
  1005. positionArray[j] = GetNIndex(t[j], i);
  1006. }
  1007. //the t is changing with positionArray;
  1008. for (int m = ; m < length; m++)
  1009. {
  1010. countArray[positionArray[m]]++;
  1011. }
  1012. for (int m = ; m < ; m++)
  1013. {
  1014. countArray[m] += countArray[m - ];
  1015. countArray[m - ]--;
  1016. }
  1017. countArray[]--;
  1018.  
  1019. for (int m = length - ; m >= ; m--)
  1020. {
  1021. //无论其他怎么改变 位置都是相对的 positionArray[m]就是t[m]
  1022. tempArray[countArray[positionArray[m]]] = t[m];
  1023. countArray[positionArray[m]]--;
  1024. }
  1025. for (int m = ; m < length; m++)
  1026. {
  1027. t[m] = tempArray[m];
  1028. }
  1029. delete[] countArray;
  1030. }
  1031.  
  1032. delete[] positionArray;
  1033. delete[] tempArray;
  1034. }
  1035.  
  1036. };
  1037. #pragma endregion
  1038.  
  1039. #pragma region std::list<T>
  1040. template<typename T>
  1041. class Sort<std::list<T>>
  1042. {
  1043. //for the list, we can't directly use the operator+/-,because it is the list
  1044. //actually we can use the operator[] to change it, does list solved the problem?
  1045. //not effective at all
  1046. //we should support a method to increase or decrease the pointer(iterator)!
  1047. typedef typename std::list<T>::iterator iterator;
  1048.  
  1049. public:
  1050. void InsertSort(std::list<T>& t)
  1051. {
  1052. for (std::list<T>::iterator it = t.begin(); it != t.end(); it++)
  1053. {
  1054. std::list<T>::iterator itFront = it;
  1055. if (++it == t.end())
  1056. {
  1057. break;
  1058. }
  1059. T temp = *it;
  1060. it--;
  1061.  
  1062. while (*itFront > temp)
  1063. {
  1064. std::list<T>::iterator itTemp = itFront;
  1065. itTemp++;
  1066. *itTemp = *itFront;
  1067. if (itFront != t.begin())
  1068. {
  1069. itFront--;
  1070. if (itFront == t.begin() && *itFront < temp)
  1071. {
  1072. itFront++;
  1073. break;
  1074. }
  1075. }
  1076. else
  1077. {
  1078. break;
  1079. }
  1080. }
  1081. *itFront = temp;
  1082. }
  1083. }
  1084.  
  1085. void MergeSort(std::list<T>& t)
  1086. {
  1087. int length = t.size();
  1088. _MergeSort(t, , length - );
  1089. }
  1090.  
  1091. void HeapSort(std::list<T>& t)
  1092. {
  1093. //the worst palce is to find the son of iterator, it will cost too much;
  1094. int length = t.size() - ;
  1095. BuildHeap(t);
  1096. iterator begin = t.begin();
  1097. iterator end = t.end();
  1098. end--;
  1099. for (int i = length; i >= ; i--)
  1100. {
  1101. T temp = *end;
  1102. *end = *begin;
  1103. *begin = temp;
  1104. MaxHeapify(t, begin, i - );
  1105. end--;
  1106. }
  1107.  
  1108. }
  1109.  
  1110. void QuickSort(std::list<T>& t)
  1111. {
  1112. _QuickSort(t, , t.size() - );
  1113. }
  1114.  
  1115. void CountingSort(std::list<T>& t)
  1116. {
  1117. //偷天换日一回,将iterator操作变换成数组操作
  1118. if (typeid(T) == typeid(int))
  1119. {
  1120. int length = t.size();
  1121. int count = ;
  1122. T* positiveArray;
  1123. T* negetiveArray;
  1124.  
  1125. iterator it;
  1126. for (it = t.begin(); it != t.end(); it++)
  1127. {
  1128. if (*it < )
  1129. {
  1130. count++;
  1131. }
  1132. }
  1133. positiveArray = new T[length-count];
  1134. negetiveArray = new T[count];
  1135. int m = , n = ;
  1136. for (it = t.begin(); it != t.end(); it++)
  1137. {
  1138. if (*it < )
  1139. {
  1140. negetiveArray[m] = *it;
  1141. m++;
  1142. }
  1143. else
  1144. {
  1145. positiveArray[n] = *it;
  1146. n++;
  1147. }
  1148. }
  1149.  
  1150. T poMin = positiveArray[], poMax = positiveArray[];
  1151. T neMin = negetiveArray[], neMax = negetiveArray[];
  1152.  
  1153. for (int i = ; i < length - count; i++)
  1154. {
  1155. if (positiveArray[i]>poMax)
  1156. {
  1157. poMax = positiveArray[i];
  1158. }
  1159. if (positiveArray[i] < poMin)
  1160. {
  1161. poMin = positiveArray[i];
  1162. }
  1163. }
  1164. for (int i = ; i <count; i++)
  1165. {
  1166. if (negetiveArray[i]>neMax)
  1167. {
  1168. neMax = negetiveArray[i];
  1169. }
  1170. if (negetiveArray[i] < neMin)
  1171. {
  1172. neMin = negetiveArray[i];
  1173. }
  1174. }
  1175. T poMinux = poMax - poMin;
  1176. T neMinux = neMax - neMin;
  1177.  
  1178. //positive array
  1179. T* positiveArrayed = new T[length - count];
  1180. T* countArrayPo = new T[poMinux + ];
  1181. memset(countArrayPo, , (poMinux + )*sizeof(T));
  1182.  
  1183. for (int i = ; i < length - count; i++)
  1184. {
  1185. countArrayPo[positiveArray[i]-poMin]++;
  1186. }
  1187. for (int i = ; i <= poMinux; i++)
  1188. {
  1189. countArrayPo[i] += countArrayPo[i - ];
  1190. countArrayPo[i - ]--;
  1191. }
  1192. countArrayPo[poMinux]--;
  1193. for (int i = length - count - ; i >= ; i--)
  1194. {
  1195. positiveArrayed[countArrayPo[positiveArray[i] - poMin]] = positiveArray[i];
  1196. countArrayPo[positiveArray[i] - poMin]--;
  1197. }
  1198. //negetive value
  1199. T* negetiveArrayed = new T[count];
  1200. T* countArrayNe = new T[neMinux + ];
  1201. memset(countArrayNe, , (neMinux + )*sizeof(T));
  1202. for (int i = ; i < count; i++)
  1203. {
  1204. countArrayNe[negetiveArray[i] - neMin]++;
  1205. }
  1206. for (int i = ; i <= neMinux; i++)
  1207. {
  1208. countArrayNe[i] += countArrayNe[i - ];
  1209. countArrayNe[i]--;
  1210. }
  1211. countArrayNe[neMinux]--;
  1212. for (int i = count - ; i >= ; i--)
  1213. {
  1214. negetiveArrayed[countArrayNe[negetiveArray[i] - neMin]] = negetiveArray[i];
  1215. countArrayNe[negetiveArray[i] - neMin]--;
  1216. }
  1217. //gather two arraies
  1218. m = , n = ;
  1219. for (it = t.begin(); it != t.end(); it++)
  1220. {
  1221. if (m < count)
  1222. {
  1223. *it = negetiveArrayed[m];
  1224. m++;
  1225. }
  1226. else
  1227. {
  1228. *it = positiveArrayed[n];
  1229. n++;
  1230. }
  1231.  
  1232. }
  1233.  
  1234. delete[] positiveArray;
  1235. delete[] negetiveArray;
  1236. delete[] countArrayPo;
  1237. delete[] countArrayNe;
  1238. delete[] positiveArrayed;
  1239. delete[] negetiveArrayed;
  1240. }
  1241. else
  1242. {
  1243. std::cout << "you are using non-list<int> type\n";
  1244. }
  1245. }
  1246.  
  1247. void RadixSort(std::list<T>& t)
  1248. {
  1249. std::list<T> positiveArray;
  1250. std::list<T> negetiveArray;
  1251.  
  1252. for (iterator it = t.begin(); it != t.end(); it++)
  1253. {
  1254. if (*it < )
  1255. {
  1256. negetiveArray.push_back(-*it);
  1257. }
  1258. else
  1259. {
  1260. positiveArray.push_back(*it);
  1261. }
  1262. }
  1263. _RadixSort(positiveArray);
  1264. _RadixSort(negetiveArray);
  1265. int i = ;
  1266. iterator itNe;
  1267. if (negetiveArray.size() == )
  1268. {
  1269. itNe = negetiveArray.end();
  1270. }
  1271. else
  1272. {
  1273. itNe = --negetiveArray.end();
  1274. }
  1275. for (iterator it = t.begin(), itPo = positiveArray.begin(); it != t.end(); it++)
  1276. {
  1277. if (i < negetiveArray.size())
  1278. {
  1279. *it = -*itNe;
  1280. i++;
  1281. if (itNe != negetiveArray.begin())
  1282. {
  1283. itNe--;
  1284. }
  1285. }
  1286. else
  1287. {
  1288. *it = *itPo;
  1289. itPo++;
  1290. }
  1291. }
  1292. }
  1293.  
  1294. void BucketSort(std::list<T>& t)
  1295. {
  1296. int length = t.size();
  1297. T max = *(t.begin()), min = *(t.begin());
  1298. for (iterator it = t.begin(); it != t.end(); it++)
  1299. {
  1300. if (*it > max)
  1301. {
  1302. max = *it;
  1303. }
  1304. if (*it < min)
  1305. {
  1306. min = *it;
  1307. }
  1308. }
  1309. int minux = max - min+;
  1310. std::vector<T>* colArray = new std::vector<T>[length];
  1311. for (iterator it = t.begin(); it != t.end(); it++)
  1312. {
  1313. int index = (*it - min)*length / minux;
  1314. colArray[index].push_back(*it);
  1315. }
  1316. for (int i = ; i < length; i++)
  1317. {
  1318. Sort<std::vector<T>> s;
  1319. s.InsertSort(colArray[i]);
  1320. }
  1321. int m = ;
  1322. //the border condition annoys me a lot!
  1323. for (iterator it = t.begin(); it != t.end(); m++)
  1324. {
  1325. for (std::vector<T>::iterator itCol = colArray[m].begin(); itCol != colArray[m].end(); itCol++)
  1326. {
  1327. *it = *itCol;
  1328. it++;
  1329. }
  1330. }
  1331. }
  1332.  
  1333. private:
  1334. void _MergeSort(std::list<T>& t, int a, int b)
  1335. {
  1336. if (a<b)
  1337. {
  1338. int c = (a + b) / ;
  1339. _MergeSort(t, a, c);
  1340. _MergeSort(t, c + , b);
  1341.  
  1342. std::list<T>::iterator ita = t.begin();
  1343. std::list<T>::iterator itc = t.begin();
  1344. std::list<T>::iterator itb = t.begin();
  1345. for (int i = ; i <= b; i++)
  1346. {
  1347. if (i<a)
  1348. {
  1349. ita++;
  1350. }
  1351. if (i<c)
  1352. {
  1353. itc++;
  1354. }
  1355. if (i<b)
  1356. {
  1357. itb++;
  1358. }
  1359. }
  1360. Merge(t, ita, itc, itb);
  1361. }
  1362.  
  1363. }
  1364.  
  1365. //Here we can't directly use the std::list<T>::iterator, use the typedef to replace it
  1366. //compiler of ms
  1367. void Merge(std::list<T>& t, iterator a, iterator c, iterator b)
  1368. {
  1369. std::list<T> temp1;
  1370. std::list<T>::iterator nothing = ++c;
  1371. c--;
  1372. for (std::list<T>::iterator it = a; it != nothing; it++)
  1373. {
  1374. temp1.push_back(*it);
  1375. }
  1376. temp1.push_back();
  1377. std::list<T> temp2;
  1378. std::list<T>::iterator something = ++b;
  1379. b--;
  1380. for (std::list<T>::iterator it = nothing; it != something; it++)
  1381. {
  1382. temp2.push_back(*it);
  1383. }
  1384. temp2.push_back();
  1385.  
  1386. std::list<T>::iterator itTemp1 = temp1.begin();
  1387. std::list<T>::iterator itTemp2 = temp2.begin();
  1388. for (std::list<T>::iterator it = a; it != something; it++)
  1389. {
  1390. if (*itTemp1 > *itTemp2)
  1391. {
  1392. *it = *itTemp2;
  1393. itTemp2++;
  1394. }
  1395. else
  1396. {
  1397. *it = *itTemp1;
  1398. itTemp1++;
  1399. }
  1400. }
  1401. }
  1402.  
  1403. iterator IteratorIncrease(std::list<T>& t, iterator it,int i)
  1404. {
  1405. iterator tempIt = it;
  1406. for (int index = ; index < i; index++)
  1407. {
  1408. if (tempIt == t.end()--)
  1409. {
  1410. return t.end();
  1411. }
  1412. tempIt++;
  1413. }
  1414. return tempIt;
  1415. }
  1416.  
  1417. iterator IteratorDecrese(std::list<T>& t, iterator it, int i)
  1418. {
  1419. iterator tempIt = it;
  1420. for (int index = ; index < i; i++)
  1421. {
  1422. if (tempIt == t.begin())
  1423. {
  1424. std::cout << "out of range with iterator in decrese";
  1425. return t.end();
  1426. }
  1427. else
  1428. {
  1429. tempIt--;
  1430. }
  1431. }
  1432. return tempIt;
  1433. }
  1434.  
  1435. int GetIteratorPosition(std::list<T>& t, iterator it)
  1436. {
  1437. int position = -;
  1438. iterator tempIt = t.begin();
  1439. for (tempIt; tempIt != t.end(); tempIt++)
  1440. {
  1441. position++;
  1442. if (tempIt == it)
  1443. {
  1444. break;
  1445. }
  1446. }
  1447. if (position >= t.size())
  1448. {
  1449. return -;
  1450. }
  1451. return position;
  1452. }
  1453.  
  1454. int GetLeftChild(std::list<T>& t, iterator it)
  1455. {
  1456. int number = -;
  1457. iterator tempIt;
  1458. for (tempIt = t.begin(); tempIt != t.end(); tempIt++)
  1459. {
  1460. number++;
  1461. if (tempIt == it)
  1462. {
  1463. break;
  1464. }
  1465. }
  1466. if (number >= t.size())
  1467. {
  1468. //the it is not one of the t'iterator;
  1469. return NULL;
  1470. }
  1471.  
  1472. int leftChild = ((number + ) << ) - ;
  1473. return leftChild;
  1474. }
  1475.  
  1476. int GetRightChild(std::list<T>& t, iterator it)
  1477. {
  1478. int number = -;
  1479. iterator tempIt;
  1480. for (tempIt = t.begin(); tempIt != t.end(); tempIt++)
  1481. {
  1482. number++;
  1483. if (tempIt == it)
  1484. {
  1485. break;
  1486. }
  1487. }
  1488. if (number >= t.size())
  1489. {
  1490. //the it is not one of the t'iterator;
  1491. return NULL;
  1492. }
  1493.  
  1494. int RightChild = (number + ) << ;
  1495. return RightChild;
  1496. }
  1497.  
  1498. void MaxHeapify(std::list<T>& t, iterator it, int length)
  1499. {
  1500. //iterator tempIt = IteratorIncrease(t, t.begin(), length);
  1501. int leftChild = GetLeftChild(t, it);
  1502. int rightChild = GetRightChild(t, it);
  1503. int i = GetIteratorPosition(t, it);
  1504.  
  1505. iterator itLeft = IteratorIncrease(t, t.begin(), leftChild);
  1506. iterator itRight = IteratorIncrease(t, t.begin(), rightChild);
  1507.  
  1508. int largest = ;
  1509. T tLargest;
  1510. if (leftChild <= length && *itLeft > *it)
  1511. {
  1512. largest = leftChild;
  1513. tLargest = *itLeft;
  1514. }
  1515. else
  1516. {
  1517. largest = i;
  1518. tLargest = *it;
  1519. }
  1520.  
  1521. if (rightChild <= length && *itRight > tLargest)
  1522. {
  1523. largest = rightChild;
  1524. tLargest = *itRight;
  1525. }
  1526.  
  1527. if (largest != i)
  1528. {
  1529. T temp = *it;
  1530. *it = tLargest;
  1531.  
  1532. if (largest == leftChild)
  1533. {
  1534. *itLeft = temp;
  1535. MaxHeapify(t, itLeft, length);
  1536. }
  1537. else
  1538. {
  1539. *itRight = temp;
  1540. MaxHeapify(t, itRight, length);
  1541. }
  1542. }
  1543. }
  1544.  
  1545. void BuildHeap(std::list<T>& t)
  1546. {
  1547. for (int i = (t.size() - ) / ; i >= ; i--)
  1548. {
  1549. iterator temp = IteratorIncrease(t, t.begin(), i);
  1550. MaxHeapify(t, temp, t.size()-);
  1551. }
  1552. }
  1553.  
  1554. void _QuickSort(std::list<T>& t, int a, int b)
  1555. {
  1556. if (a < b)
  1557. {
  1558. int s = Partition(t, a, b);
  1559. _QuickSort(t, a, s - );
  1560. _QuickSort(t, s + , b);
  1561. }
  1562. }
  1563.  
  1564. int Partition(std::list<T>& t, int a, int b)
  1565. {
  1566. iterator l = IteratorIncrease(t, t.begin(), a);
  1567. iterator r = IteratorIncrease(t, t.begin(), b);
  1568.  
  1569. T split = *l;
  1570. while (a < b && l != t.end() && r != t.end())
  1571. {
  1572. while (a<b && *r>split)
  1573. {
  1574. b--;
  1575. r--;
  1576. }
  1577. T temp = *r;
  1578. *r = *l;
  1579. *l = temp;
  1580.  
  1581. while (a<b && *l < split)
  1582. {
  1583. a++;
  1584. l++;
  1585. }
  1586. temp = *l;
  1587. *l = *r;
  1588. *r = temp;
  1589. }
  1590. return a;
  1591. }
  1592.  
  1593. inline int GetNIndex(int t, int i)
  1594. {
  1595. return (t % (int)pow(, i + ) - t % (int)pow(, i)) / pow(, i);
  1596. }
  1597.  
  1598. void _RadixSort(std::list<T>& t)
  1599. {
  1600. int length = t.size();
  1601. if (length == )
  1602. {
  1603. return;
  1604. }
  1605. T max = *t.begin();
  1606. int count = ;
  1607. for (iterator it = t.begin(); it != t.end(); it++)
  1608. {
  1609. if (*it > max)
  1610. {
  1611. max = *it;
  1612. }
  1613. }
  1614. int k = max / pow(, count);
  1615. while (k != )
  1616. {
  1617. count++;
  1618. k = max / pow(, count);
  1619. }
  1620.  
  1621. T* tempArray = new int[length];
  1622. for (int i = ; i < count; i++)
  1623. {
  1624. int* positionArray = new int[length];
  1625. int* countArray = new int[];
  1626. memset(countArray, , * sizeof(int));
  1627.  
  1628. iterator it = t.begin();
  1629. for (int j = ; j < length; j++)
  1630. {
  1631. positionArray[j] = GetNIndex(*it, i);
  1632. it++;
  1633. }
  1634.  
  1635. for (int m = ; m < length; m++)
  1636. {
  1637. countArray[positionArray[m]]++;
  1638. }
  1639. for (int m = ; m < ; m++)
  1640. {
  1641. countArray[m] += countArray[m - ];
  1642. countArray[m - ]--;
  1643. }
  1644. countArray[]--;
  1645. //
  1646. it = --t.end();
  1647. for (int m = length - ; m >= ; m--)
  1648. {
  1649. tempArray[countArray[positionArray[m]]] = *it;
  1650. countArray[positionArray[m]]--;
  1651. if (it != t.begin())
  1652. {
  1653. it--;
  1654. }
  1655. }
  1656. int m = ;
  1657. for (it = t.begin(); it != t.end(); it++)
  1658. {
  1659. *it = tempArray[m];
  1660. m++;
  1661. }
  1662. delete[] positionArray;
  1663. delete[] countArray;
  1664. }
  1665. delete[] tempArray;
  1666. }
  1667. };
  1668.  
  1669. #pragma endregion

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

模板化的七种排序算法,适用于T* vector<T>以及list<T>的更多相关文章

  1. 数据结构(三) 用java实现七种排序算法。

    很多时候,听别人在讨论快速排序,选择排序,冒泡排序等,都觉得很牛逼,心想,卧槽,排序也分那么多种,就觉得别人很牛逼呀,其实不然,当我们自己去了解学习后发现,并没有想象中那么难,今天就一起总结一下各种排 ...

  2. C语言中的七种排序算法

    堆排序: void HeapAdjust(int *arraydata,int rootnode,int len) { int j; int t; *rootnode+<len) { j=*ro ...

  3. 几种排序算法的学习,利用Python和C实现

    之前学过的都忘了,也没好好做过总结,现在总结一下. 时间复杂度和空间复杂度的概念: 1.空间复杂度:是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了,简单说就是递归集算 ...

  4. PHP的几种排序算法的比较

    这里列出了几种PHP的排序算法的时间比较的结果,,希望对大家有所帮助 /* * php 四种排序算法的时间与内置的sort排序比较 * 3000个元素,四种算法的排序所用的时间比较 * 冒泡排序 85 ...

  5. Java 的八种排序算法

    Java 的八种排序算法 这个世界,需要遗忘的太多. 背景:工作三年,算法一问三不知. 一.八种排序算法 直接插入排序.希尔排序.简单选择排序.堆排序.冒泡排序.快速排序.归并排序和基数排序. 二.算 ...

  6. 秒杀9种排序算法(JavaScript版)

    一:你必须知道的 1> JS原型 2> 排序中的有序区和无序区 3> 二叉树的基本知识 如果你不知道上面三个东西,还是去复习一下吧,否则,看下面的东西有点吃力. 二:封装丑陋的原型方 ...

  7. 学习Java绝对要懂的,Java编程中最常用的几种排序算法!

    今天给大家分享一下Java中几种常见的排序算法的Java代码 推荐一下我的Java学习羊君前616,中959,最后444.把数字串联起来!     ,群里有免费的学习视频和项目给大家练手.大神有空时也 ...

  8. C#常用8种排序算法实现以及原理简介

    public static class SortExtention { #region 冒泡排序 /* * 已知一组无序数据a[1].a[2].--a[n],需将其按升序排列.首先比较a[1]与a[2 ...

  9. 排序—时间复杂度为O(n2)的三种排序算法

    1 如何评价.分析一个排序算法? 很多语言.数据库都已经封装了关于排序算法的实现代码.所以我们学习排序算法目的更多的不是为了去实现这些代码,而是灵活的应用这些算法和解决更为复杂的问题,所以更重要的是学 ...

随机推荐

  1. Unity 重要基础知识点

    这是两个月前的学习记录,发出来了下,如果有误欢迎大家指出: 脚本生命周期 //每当脚本被加载时调用一次 // 1.   在Awake中做一些初始化操作 void Awake(){ //初始化publi ...

  2. svn cleanup 执行失败时,可以勾选 break locks,

  3. angular2环境搭建

    Angular2.x与Angular1.x完全不同,Angular2.x是不兼容Angular1.x的,所在在框架的构造上,它们是完全不同的.在Angular2.x中,因为其是基于ES6来开发的,所以 ...

  4. 使用ANTS Performance Profiler&ANTS Memory Profiler工具分析IIS进程内存和CPU占用过高问题

    一.前言 最近一段时间,网站经常出现两个问题: 1.内存占用率一点点增高,直到将服务器内存占满. 2.访问某个页面时,页面响应过慢,CPU居高不下. 初步判断内存一点点增多可能是因为有未释放的资源一直 ...

  5. Ajax入门(二)

    接收服务器返回的消息 1,定义触发Ajax的js效果 2,创建Ajax方法 如果返回的数据是XML,则需使用aj.responseXML 3,接收服务器返回的消息,并显示在网页上 错误案例:直接接收服 ...

  6. java Ajax的应用

    一.Ajax的使用步骤 步一:创建AJAX异步对象,例如:createAJAX() 步二:准备发送异步请求,例如:ajax.open(method,url) 步三:如果是POST请求的话,一定要设置A ...

  7. string常用函数

    1.addslashes($str); //转义时str中的所有特殊字符 stripslashes($str) //还原 2.bin2hex($str); //将2进制转成16进制 3. echo c ...

  8. Java集合框架List,Map,Set等全面介绍

    Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I]   +--java.util.ArrayList [C]   +- ...

  9. STM32用JLINK 烧写程序时出现NO Cortex-m device found in JTAG chain现象和解决方案

    现象 CPU: STM32107VC 用JLINK 烧写程序时出现NO Cortex-m device found in JTAG chain 如图无法查找到硬件就是CPU 提示1:NO Cortex ...

  10. jquery实现input输入框实时输入触发事件代码(点击历史记录也会触发)

    $("#email").bind('input propertychange', function() { if(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0 ...