nanxing_basic_sort.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #ifndef _NANXING_SORT_BASIC_H_
  2. #define _NANXING_SORT_BASIC_H_
  3. #include"nanxing_operator_check.h"
  4. #include"../nanxing_type_trait.h"
  5. #include<type_traits>
  6. #include<iostream>
  7. #include<climits>
  8. namespace nanxing{
  9. template<typename T>
  10. class sort //这里的T类型必须是一个指针类型否则会报错
  11. {
  12. public:
  13. static_assert(NANXING_BASIC_OPERATOR_(T,index),"It cannot be indexed"); //检查T类型能否下标访问
  14. static_assert(NANXING_BASIC_OPERATOR_(T,compare_ptr),"The data pointed cannot compared"); //检查指向的数据能否比较大小
  15. static_assert(NANXING_BASIC_OPERATOR_(T,equal_ptr),"The data pointed cannot assign value"); //检查指向的数据能否相互赋值
  16. void operator()(T data,size_t size) //默认的sort用快速排序
  17. {
  18. fast_sort(data,0,size-1);
  19. }
  20. static void fast_sort(T data,size_t left,size_t right) //快速排序
  21. {
  22. if(right<=left)
  23. {
  24. return;
  25. }
  26. using ptr_type=nanxing::remove_pointer<T>::type;
  27. ptr_type middle;
  28. //选取最后一个数字作为枢纽元(如果不是最后一个就将枢纽元和right元素交换)
  29. int i=left;
  30. int j=right-1;
  31. middle;
  32. if((right-left)<=3) //当划分的长度小于3的时候用直接插入排序
  33. {
  34. for(int i=left+1;i<=right;i++)
  35. {
  36. for(int j=i;j>left;j--)
  37. {
  38. if(data[j]<data[j-1])
  39. {
  40. middle=data[j];
  41. data[j]=data[j-1];
  42. data[j-1]=middle;
  43. }
  44. }
  45. }
  46. return;
  47. }
  48. for(;;)
  49. {
  50. while(data[i]<=data[right]&&i<right){i++;}
  51. while(data[j]>data[right]&&j>left){j--;} //注意书上的例程没有考虑一种非常特殊的情况即在ij同时等于枢纽元
  52. if(i<j)
  53. {
  54. middle=data[i];
  55. data[i]=data[j];
  56. data[j]=middle;
  57. }
  58. else{
  59. break;
  60. }
  61. }
  62. middle=data[i];
  63. data[i]=data[right];
  64. data[right]=middle;
  65. fast_sort(data,left,i-1);
  66. fast_sort(data,i+1,right);
  67. }
  68. static void bubble_sort(T data,size_t size) //冒泡排序
  69. {
  70. using ptr_type=nanxing::remove_pointer<T>::type;
  71. ptr_type middle;
  72. for(int i=0;i<size;size--)
  73. {
  74. for(int j=i;j<size-1;j++)
  75. {
  76. if(data[j]>data[j+1])
  77. {
  78. middle =data[j+1];
  79. data[j+1]=data[j];
  80. data[j]=middle;
  81. }
  82. }
  83. }
  84. }
  85. static void strait_insert_sort(T data, size_t size) //直接插入排序
  86. {
  87. using ptr_type=nanxing::remove_pointer<T>::type;
  88. ptr_type middle;
  89. for(size_t i=1;i<size;i++)
  90. {
  91. for(int j=i;j>0;j--)
  92. {
  93. if(data[j]<data[j-1])
  94. {
  95. middle=data[j];
  96. data[j]=data[j-1];
  97. data[j-1]=middle;
  98. }
  99. else{
  100. break;
  101. }
  102. }
  103. }
  104. }
  105. static void select_sort(T data,size_t size) //选择排序
  106. {
  107. using ptr_type=nanxing::remove_pointer<T>::type;
  108. ptr_type min;
  109. ptr_type middle;
  110. int n=0;
  111. for(int i=0;i<size;i++)
  112. {
  113. min=data[i];
  114. n=i;
  115. for(int j=i;j<size;j++)
  116. {
  117. if(data[j]<min)
  118. {
  119. n=j;
  120. min=data[j];
  121. }
  122. }
  123. data[n]=data[i];
  124. data[i]=min;
  125. }
  126. }
  127. static void heap_sort(T data,size_t size) //堆排序
  128. {
  129. using ptr_type=nanxing::remove_pointer<T>::type;
  130. ptr_type middle;
  131. size_t middle_size=size;
  132. for(int i=static_cast<int>(middle_size/2-1);i>=0;i--) //构建堆
  133. {
  134. build_heap(data,i,size);
  135. }
  136. for(size_t i=size-1;i>0;i--)
  137. {
  138. middle=data[0];
  139. data[0]=data[i];
  140. data[i]=middle;
  141. build_heap(data,0,i);
  142. }
  143. }
  144. static void Hill_sort(T data,size_t jump,size_t size) //希尔排序
  145. {
  146. using ptr_type=nanxing::remove_pointer<T>::type;
  147. ptr_type middle;
  148. if(jump*2>=size-1) //如果跳跃的间隔过大就直接用直接插入排序
  149. {
  150. strait_insert_sort(data,size);
  151. return;
  152. }
  153. for(int i=0;i<jump;i++) //分组做直接插入排序
  154. {
  155. for(int j=i+jump;j<size;j+=jump)
  156. {
  157. for(int k=j;k>=jump;k-=jump)
  158. {
  159. if(data[k]<data[k-jump])
  160. {
  161. middle=data[k-jump];
  162. data[k-jump]=data[k];
  163. data[k]=middle;
  164. }
  165. else{
  166. break;
  167. }
  168. }
  169. }
  170. }
  171. strait_insert_sort(data,size);
  172. }
  173. static void Print(T data,size_t size)
  174. {
  175. for(int i=0;i<size-1;i++)
  176. {
  177. std::cout<<data[i]<<" "<<","<<" ";
  178. }
  179. std::cout<<data[size-1]<<std::endl;
  180. }
  181. private:
  182. static void build_heap(T data ,size_t S,size_t size) //除了S之外的所有点都满足大顶堆的定义
  183. {
  184. using ptr_type=typename nanxing::remove_pointer<T>::type;
  185. ptr_type middle=data[S];
  186. int middle_s=S;
  187. for(int j=2*middle_s+1;j<=(size-1);j=j*2+1) //这个是左孩子
  188. {
  189. if(j<size-1&&data[j]<data[j+1]) //注意这里的范围j<size-1,size是其中点的数量,但是下标从0开始的
  190. {
  191. j++;
  192. }
  193. if(middle>data[j]){
  194. break;
  195. }
  196. else{
  197. data[middle_s]=data[j];
  198. middle_s=j;
  199. }
  200. }
  201. data[middle_s]=middle;
  202. }
  203. private:
  204. unsigned int amount;
  205. //T* sort_data_ptr; //指向需要排序的数据(一个数组或者一个vector之类的指针)
  206. //T& sort_data_ptr; //原始数据的引用
  207. };
  208. }
  209. #endif