归并合并简单来说就是先将数组分成组,然后再将组有序的合并起来。
我们可以拿一个例子来分析一下。
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]