归并排序
归并排序算法是用分治策略实现对n个元素进行排序的算法。
其基本思想是:将待排序的元素分成大小大致相同的两个子集合,分别对2个子集合进行排序,最终将排序好的子集合合并成为所要求的排好序的集合。
递归版本算法(不完全版本):
1 public static void mergeSort(Comparable a[],int left,int right){ 2 if(left<right){//至少有两个元素 3 int i=(left+right)/2; //取中点 4 mergeSort(a,left,i); 5 mergeSort(a, i+1, right); 6 merge(a,b,left,right); //合并到数组b 7 copy(a,b,left,right); //复制回数组a 8 } 9 }
非递归版本实现:
可以看出,算法mergeSort的递归过程只是将待排序集合一分为二,直至待排序的集合只剩下一个元素为止。然后不断合并2个排序好的子集合。
由此可以想到,我们可以先将数组a中相邻元素两两配对。用合并算法将他们排序,构成n/2组长度为2的排好序的子集合,然后将它们排序成长度为4
的子集合,如此继续下去,直至整个数组排好序。
这样一来就可以消除递归了。
1 public class MergeSort { 2 3 // 非递归版本归并排序 4 @SuppressWarnings("rawtypes") 5 public static void mergeSort(Comparable[] a) { 6 Comparable b[] = new Comparable[a.length]; 7 int s = 1; 8 while (s < a.length) { 9 // a,b交替保证了a一直是有序的 10 mergePass(a, b, s); 11 s = s * 2; 12 mergePass(b, a, s); 13 s = s * 2; 14 } 15 } 16 17 @SuppressWarnings("rawtypes") 18 private static void mergePass(Comparable[] x, Comparable[] y, int s) { 19 // 合并大小为s的相邻子数组 20 int i = 0; 21 while (i + 2 * s <= x.length) { 22 // 合并大小为s的相邻2段子数组,x[i,i+s-1],x[i+s-1,i+2*s-1] 23 merge(x, y, i, i + s - 1, i + 2 * s - 1); 24 i = i + 2 * s; 25 } 26 27 if (i + s < x.length) { 28 // 剩下的元素个数大于s小于2s,仍然要合并 29 merge(x, y, i, i + s - 1, i + 2 * s - 1); 30 } else { 31 // i+s>=x.length的时候,此时剩余的元素个数小于s, 当小于s的时候已经是有序的,直接把剩余元素添加到y的末尾 32 for (; i < y.length; i++) 33 y[i] = x[i]; 34 } 35 } 36 37 @SuppressWarnings({ "rawtypes", "unchecked" }) 38 private static void merge(Comparable[] copy, Comparable[] to, int left, 39 int middle, int right) { 40 // 合并copy[left,middle]和to[middle+1,right]到to[left,right] 41 int i = left, j = middle + 1, k = left; 42 43 while (i <= middle && j <= right) { 44 if (copy[i].compareTo(copy[j]) <= 0) // 由小到大排序 45 to[k++] = copy[i++]; 46 else 47 to[k++] = copy[j++]; 48 } 49 50 /* 51 * 以下两个循环用于将剩下已经有序的元素添加到to的末尾, 其中一个数组最大的元素n已经在to中,另外一个数组的元素肯定大于等于n, 52 * 因此直接添加就行 53 */ 54 while (i <= middle) 55 to[k++] = copy[i++]; 56 while (j <= right) 57 to[k++] = copy[j++]; 58 } 59 60 @SuppressWarnings("rawtypes") 61 public static void main(String[] args) { 62 Comparable a[] = { 4, 6, 7, 1, 2, 5, 9, 0 }; 63 mergeSort(a); 64 for (int i = 0; i < a.length; i++) 65 System.out.print(" "+a[i]); 66 } 67 68 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。