免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1570 | 回复: 0
打印 上一主题 下一主题

经典的排序算法java实现版 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-06-02 10:26 |只看该作者 |倒序浏览
  1. /**
  2.   2  *
  3.   3  * @author yuzhiping
  4.   4  * @version 1.0
  5.   5  * 功能说明:计算机领域经典的算法
  6.   6  *
  7.   7  */
  8.   8 public class sortAlgorithm<T extends Comparable<T>> {
  9.   9     
  10. 10     //交换索引i和索引j的值
  11. 11     private void swap(T [] data ,int i,int j){
  12. 12         T tmp;
  13. 13         tmp=data[i];
  14. 14         data[i]=data[j];
  15. 15         data[j]=tmp;
  16. 16     }
  17. 17     
  18. 18     
  19. 19     //-----堆排序 时间复杂度O(nlogn)-----
  20. 20     
  21. 21     public void heapSort(T [] data){
  22. 22         int arrayLength=data.length;
  23. 23         //循环件堆
  24. 24         for(int i=0;i<arrayLength-1;i++){
  25. 25             // 建堆
  26. 26             builMaxdHeap(data, arrayLength - 1 - i);
  27. 27             // 交换堆顶和最后一个元素
  28. 28             swap(data, 0, arrayLength - 1 - i);
  29. 29
  30. 30         }
  31. 31     }
  32. 32     
  33. 33     // 对data数组从0到lastIndex建大顶堆
  34. 34     private void builMaxdHeap(T[] data, int lastIndex) {
  35. 35         // 从lastIndex处节点(最后一个节点)的父节点开始
  36. 36         for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
  37. 37             // k保存当前正在判断的节点
  38. 38             int k = i;
  39. 39             // 如果当前k节点的子节点存在
  40. 40             while (k * 2 + 1 <= lastIndex) {
  41. 41                 // k节点的左子节点的索引
  42. 42                 int biggerIndex = 2 * k + 1;
  43. 43                 // 如果biggerIndex小于lastIndex,即biggerIndex + 1
  44. 44                 // 代表的k节点的右子节点存在
  45. 45                 if (biggerIndex < lastIndex) {
  46. 46                     // 如果右子节点的值较大
  47. 47                     if (data[biggerIndex].compareTo(data[biggerIndex + 1]) < 0) {
  48. 48                         // biggerIndex总是记录较大子节点的索引
  49. 49                         biggerIndex++;
  50. 50                     }
  51. 51                 }
  52. 52                 // 如果k节点的值小于其较大子节点的值
  53. 53                 if (data[k].compareTo(data[biggerIndex]) < 0) {
  54. 54                     // 交换它们
  55. 55                     swap(data, k, biggerIndex);
  56. 56                     // 将biggerIndex赋给k,开始while循环的下一次循环,
  57. 57                     // 重新保证k节点的值大于其左、右子节点的值。
  58. 58                     k = biggerIndex;
  59. 59                 } else {
  60. 60                     break;
  61. 61                 }
  62. 62             }
  63. 63         }
  64. 64     }
  65. 65      
  66. 66     //-----冒泡排序法 时间复杂度O(n^2)-----
  67. 67     public void bubbleSort(T[] data){
  68. 68         int i,j;
  69. 69         for(i=0;i<data.length-1;i++){
  70. 70             for(j=0;j<data.length-i-1;j++){
  71. 71                 if(data[j].compareTo(data[j+1]) > 0){
  72. 72                     swap(data,j+1,j);
  73. 73                 }
  74. 74             }
  75. 75         }
  76. 76     }
  77. 77      
  78. 78     //-----选择排序法 时间复杂度O(n^2)-----
  79. 79     public void selectSort(T[] data){
  80. 80         int i,j;   
  81. 81         
  82. 82         for(i=0;i<data.length-1;i++){
  83. 83             for(j=i+1;j<data.length;j++){
  84. 84                 if (data[i].compareTo(data[j]) > 0){
  85. 85                     swap(data,i,j);
  86. 86                 }
  87. 87             }
  88. 88         }
  89. 89     }
  90. 90      
  91. 91     //-----快速排序法  时间复杂度为O(log2n)-----
  92. 92     public void quickSort(T[] data){
  93. 93         subQuickSort(data,0,data.length-1);
  94. 94     }
  95. 95      
  96. 96     private void subQuickSort(T[] data,int start,int end){
  97. 97         if( start < end ){
  98. 98             //以第一个元素作为分界值
  99. 99             T base = data[start];
  100. 100             //i从左边开始搜索大于分界值元素的索引
  101. 101             int i = start;
  102. 102             //j从右边开始搜索小于分界值元素的索引
  103. 103             int j = end + 1;
  104. 104             while(true){
  105. 105                 //左边跳过比base小的元素
  106. 106                 while(i < end && data[++i].compareTo(base) <= 0);
  107. 107                 //右边跳过比base大的元素
  108. 108                 while(j > start && data[--j].compareTo(base) >= 0);
  109. 109                  
  110. 110                 if(j > i){
  111. 111                     swap(data,i,j);
  112. 112                 }else{
  113. 113                     break;
  114. 114                 }
  115. 115             }
  116. 116             //将分界值还原
  117. 117             swap(data,start,j);
  118. 118              
  119. 119             //递归左边序列
  120. 120             subQuickSort(data,start,j-1);
  121. 121             //递归右边序列
  122. 122             subQuickSort(data,j+1,end);
  123. 123         }
  124. 124     }
  125. 125      
  126. 126     //-----插入排序法 时间复杂度O(n^2)-----
  127. 127     public void insertSort(T[] data){
  128. 128         int arrayLength = data.length;
  129. 129         
  130. 130         for(int i=1;i<arrayLength;i++){
  131. 131             //当整体后移时保证data[i]的值不会丢失
  132. 132             T tmp = data[i];
  133. 133             //i索引处的值已经比前面所有值都大,表明已经有序,无需插入
  134. 134             //i-1处索引之前的数值已经有序,i-1处索引处元素的值也是最大值
  135. 135             if(data[i].compareTo(data[i-1]) < 0){
  136. 136                 int j = i-1;
  137. 137                 //整体后移一个
  138. 138                 while(j>=0 && data[j].compareTo(tmp) > 0){
  139. 139                     data[j+1] = data[j];
  140. 140                     j--;
  141. 141                 }
  142. 142             data[j+1] = tmp;
  143. 143             }
  144. 144         }
  145. 145     }
  146. 146      
  147. 147     //-----折半插入排序法 时间复杂度-----
  148. 148     public void binaryInsertSort(T[] data) {
  149. 149         int arrayLength = data.length;
  150. 150  
  151. 151         for (int i = 1; i < arrayLength; i++) {
  152. 152             if (data[i - 1].compareTo(data[i]) > 0) {
  153. 153                 // 缓存i处的元素值
  154. 154                 T tmp = data[i];
  155. 155  
  156. 156                 // 记录搜索范围的左边界
  157. 157                 int low = 0;
  158. 158                 // 记录搜索范围的右边界
  159. 159                 int high = i - 1;
  160. 160  
  161. 161                 while (high >= low) {
  162. 162                     // 记录中间位置
  163. 163                     int mid = (high + low) / 2;
  164. 164                     // 比较中间位置数据和i处数据大小,以缩小搜索范围
  165. 165  
  166. 166                     if (tmp.compareTo(data[mid]) > 0) {
  167. 167                         low = mid + 1;
  168. 168                     } else {
  169. 169                         high = mid - 1;
  170. 170                     }
  171. 171                 }
  172. 172                 // 将low~i处数据整体向后移动1位
  173. 173                 for (int j = i; j > low; j--) {
  174. 174                     data[j] = data[j - 1];
  175. 175                 }
  176. 176                 data[low] = tmp;
  177. 177  
  178. 178             }
  179. 179         }
  180. 180     }
  181. 181      
  182. 182     //-----希尔排序法 时间复杂度O(nlogn)O(n^2)具体看h的值-----
  183. 183     public void shellSort(T[] data){
  184. 184         int arrayLength = data.length;
  185. 185         //h保存可变增量
  186. 186         
  187. 187         int h = 1;
  188. 188         while(h<=arrayLength/3){
  189. 189             h = h * 3 + 1;
  190. 190         }
  191. 191         
  192. 192         while(h > 0){
  193. 193             //System.out.println(Arrays.toString( data )+"h="+h);
  194. 194              
  195. 195             for(int i=h;i<arrayLength;i++){
  196. 196                 //当整体后移时,保证data[i]的值不丢失
  197. 197                 T tmp = data[i];
  198. 198                 //i索引处的值已经比前面所有的值大
  199. 199                 //(i-1索引之前的值已经有序的,i-1索引处元素的值就是最大值)
  200. 200                 if(data[i].compareTo(data[i-h]) < 0){
  201. 201                     int j = i-h;
  202. 202                     //整体后移一格
  203. 203                     while(j>=0 && data[j].compareTo(tmp) > 0){
  204. 204                         data[j+h] = data[j];
  205. 205                         j-=h;
  206. 206                     }
  207. 207                     
  208. 208                     //最后将tmp值插入合适的位置
  209. 209                     data[j+h] = tmp;
  210. 210                 }
  211. 211             }
  212. 212             h = (h-1)/3;
  213. 213         }
  214. 214         
  215. 215     }
  216. 216      
  217. 217     //-----归并排序法 时间复杂度为O(nlog2n)-----
  218. 218     public void mergeSort(T[] data){
  219. 219         subMergeSort(data,0,data.length-1);
  220. 220     }
  221. 221      
  222. 222     private void subMergeSort(T[] data,int left,int right){
  223. 223         if(right > left){
  224. 224             //找出中间索引
  225. 225             //System.out.println(  Arrays.toString(data) );
  226. 226             int center = (left + right)/2;
  227. 227             //对左边数组进行递归
  228. 228             subMergeSort(data,left,center);
  229. 229             //对右边数组进行递归
  230. 230             subMergeSort(data,center+1,right);
  231. 231             //合并
  232. 232             merge(data,left,center,right);
  233. 233         }
  234. 234     }
  235. 235      
  236. 236     @SuppressWarnings("unchecked")
  237. 237     private void merge(T[] data, int left, int center, int right) {
  238. 238         Object[] tmpArr = new Object[data.length];
  239. 239         int mid = center + 1;
  240. 240         // third记录中间处索引
  241. 241         int third = left;
  242. 242         int tmp = left;
  243. 243  
  244. 244         while (left <= center && mid <= right) {
  245. 245             // 从两个数组中取出最小的放入中间数组
  246. 246             if (data[left].compareTo(data[mid]) <= 0) {
  247. 247                 tmpArr[third++] = data[left++];
  248. 248             } else {
  249. 249                 tmpArr[third++] = data[mid++];
  250. 250             }
  251. 251         }
  252. 252         
  253. 253         // 剩余部分依次放入中间数组
  254. 254         while (mid <= right) {
  255. 255             tmpArr[third++] = data[mid++];
  256. 256         }
  257. 257         while (left <= center) {
  258. 258             tmpArr[third++] = data[left++];
  259. 259         }
  260. 260         
  261. 261         // 将中间数组的内容复制拷回原数组
  262. 262         // (原left~right范围内德内容被复制回原数组)
  263. 263         while (tmp <= right) {
  264. 264             data[tmp] = (T) tmpArr[tmp++];
  265. 265         }
  266. 266     }
  267. 267      
  268. 268
  269. 269
  270. 270     public static void main(String[] args) {
  271. 271         // TODO Auto-generated method stub
  272. 272
  273. 273     }
  274. 274
  275. 275 }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP