归并排序
归并合并简单来说就是先将数组分成组,然后再将组有序的合并起来。
我们可以拿一个例子来分析一下。
1 3 5 2 7 4 0
我们将上面的数组分成两两一组(剩下不够一组的则单独分成一组)。
【1 3】【5 2】【7 4】【0】
拿出两个组来进行有序的合并。
【1 3】【5 2】合并为【1 2 3 5】
【4 7】【0】合并为【0 4 7】
所以现在得到的是1 2 3 5 0 2 7
继续分组【1 2 3 5】【0 4 7】
有序合并【0 1 2 3 4 5 7】
下面我们来详细的说一下合并的过程。
下面把 s1 和 s2 向后移动到下面的子数组即可。直到 s2 超出数组长度。
下面我们用 java 来算法实现一下这个算法。
public static void merge(int[] array,int gap){ int start1 = 0; int end1 = start1 + gap - 1; int start2 = end1 + 1; int end2 = start2 + gap - 1 < array.length ? start2 + gap - 1 : array.length - 1; //排序 int [] tmp = new int[array.length]; int i = 0; while(start2 < array.length){ //两个归并段是否都有数据 while(start1 <= end1 && start2 <= end2){ if(array[start1] < array[start2]){ tmp[i++] = array[start1++]; }else{ tmp[i++] = array[start2++]; } } while(start1 <= end1){ tmp[i++] = array[start1++]; } while(start2 <= end2){ tmp[i++] = array[start2++]; } start1 = end2 + 1; end1 = start1 + gap - 1; start2 = end1 + 1; end2 = start2 + gap - 1 < array.length ? start2 + gap - 1 : array.length - 1; } while(start1 < array.length){ tmp[i++] = array[start1++]; } for(int j = 0;j < tmp.length;j++){ array[j] = tmp[j]; } } public static void mergeSort(int[] array){ for(int i = 1;i < array.length;i = i*2){ merge(array,i); } }
结果测试:
int[] array ={12,5,9,34,6,8,33,56,89,0,7,4,22,59,77}; int[] array2 = {23,4,34,54,65,76,22,3,56,13,35,28,32,43,5}; int[] array3 = {12,5,22,4,12,10,6}; //归并 mergeSort(array); mergeSort(array2); mergeSort(array3); System.out.println(Arrays.toString(array)); System.out.println(Arrays.toString(array2)); System.out.println(Arrays.toString(array3));
结果为:
[0, 4, 5, 6, 7, 8, 9, 12, 22, 33, 34, 56, 59, 77, 89]
[3, 4, 5, 13, 22, 23, 28, 32, 34, 35, 43, 54, 56, 65, 76]
[4, 5, 6, 10, 12, 12, 22]