nanxing_basic_sort.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. {
  60. break;
  61. }
  62. }
  63. middle=data[i];
  64. data[i]=data[right];
  65. data[right]=middle;
  66. fast_sort(data,left,i-1);
  67. fast_sort(data,i+1,right);
  68. }
  69. static void bubble_sort(T data,size_t size) //冒泡排序
  70. {
  71. using ptr_type=nanxing::remove_pointer<T>::type;
  72. ptr_type middle;
  73. for(int i=0;i<size;size--)
  74. {
  75. for(int j=i;j<size-1;j++)
  76. {
  77. if(data[j]>data[j+1])
  78. {
  79. middle =data[j+1];
  80. data[j+1]=data[j];
  81. data[j]=middle;
  82. }
  83. }
  84. }
  85. }
  86. static void strait_insert_sort(T data, size_t size) //直接插入排序
  87. {
  88. using ptr_type=nanxing::remove_pointer<T>::type;
  89. ptr_type middle;
  90. for(size_t i=1;i<size;i++)
  91. {
  92. for(int j=i;j>0;j--)
  93. {
  94. if(data[j]<data[j-1])
  95. {
  96. middle=data[j];
  97. data[j]=data[j-1];
  98. data[j-1]=middle;
  99. }
  100. else
  101. {
  102. break;
  103. }
  104. }
  105. }
  106. }
  107. static void select_sort(T data,size_t size) //选择排序
  108. {
  109. using ptr_type=nanxing::remove_pointer<T>::type;
  110. ptr_type min;
  111. ptr_type middle;
  112. int n=0;
  113. for(int i=0;i<size;i++)
  114. {
  115. min=data[i];
  116. n=i;
  117. for(int j=i;j<size;j++)
  118. {
  119. if(data[j]<min)
  120. {
  121. n=j;
  122. min=data[j];
  123. }
  124. }
  125. data[n]=data[i];
  126. data[i]=min;
  127. }
  128. }
  129. static void heap_sort(T data,size_t size) //堆排序
  130. {
  131. using ptr_type=nanxing::remove_pointer<T>::type;
  132. ptr_type middle;
  133. size_t middle_size=size;
  134. for(int i=static_cast<int>(middle_size/2-1);i>=0;i--) //构建堆
  135. {
  136. build_heap(data,i,size);
  137. }
  138. for(size_t i=size-1;i>0;i--)
  139. {
  140. middle=data[0];
  141. data[0]=data[i];
  142. data[i]=middle;
  143. build_heap(data,0,i);
  144. }
  145. }
  146. static void Hill_sort(T data,size_t jump,size_t size) //希尔排序
  147. {
  148. using ptr_type=nanxing::remove_pointer<T>::type;
  149. ptr_type middle;
  150. if(jump*2>=size-1) //如果跳跃的间隔过大就直接用直接插入排序
  151. {
  152. strait_insert_sort(data,size);
  153. return;
  154. }
  155. for(int i=0;i<jump;i++) //分组做直接插入排序
  156. {
  157. for(int j=i+jump;j<size;j+=jump)
  158. {
  159. for(int k=j;k>=jump;k-=jump)
  160. {
  161. if(data[k]<data[k-jump])
  162. {
  163. middle=data[k-jump];
  164. data[k-jump]=data[k];
  165. data[k]=middle;
  166. }
  167. else{
  168. break;
  169. }
  170. }
  171. }
  172. }
  173. strait_insert_sort(data,size);
  174. }
  175. static void Print(T data,size_t size)
  176. {
  177. for(int i=0;i<size-1;i++)
  178. {
  179. std::cout<<data[i]<<" "<<","<<" ";
  180. }
  181. std::cout<<data[size-1]<<std::endl;
  182. }
  183. private:
  184. static void build_heap(T data ,size_t S,size_t size) //除了S之外的所有点都满足大顶堆的定义
  185. {
  186. using ptr_type=typename nanxing::remove_pointer<T>::type;
  187. ptr_type middle=data[S];
  188. int middle_s=S;
  189. for(int j=2*middle_s+1;j<=(size-1);j=j*2+1) //这个是左孩子
  190. {
  191. if(j<size-1&&data[j]<data[j+1]) //注意这里的范围j<size-1,size是其中点的数量,但是下标从0开始的
  192. {
  193. j++;
  194. }
  195. if(middle>data[j])
  196. {
  197. break;
  198. }
  199. else{
  200. data[middle_s]=data[j];
  201. middle_s=j;
  202. }
  203. }
  204. data[middle_s]=middle;
  205. }
  206. private:
  207. unsigned int amount;
  208. };
  209. }
  210. #endif