归并排序(Merge Sort)是分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列之间有序。将两个有序数组合并成一个有序数组,称为二路归并(binary merge)。
图解为实现的思路。(图是借来的)
伪代码实现主要分为
1.第一步先把数组以一分为二的形式分到最小的单元
2.用指针的形式标记在左右数组的两边最开始的位置
3.对比左边和右边的元素大小,把最小放置到临时数组中,并标记临时数组的的索引下标变化。
4.把临时数组赋值到原数组中
public class MergeSortThree {
public static void main(String[] args) {
int a[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
sort(a,0,a.length-1);
System.out.println(Arrays.toString(a));
}
/*
* 归并排序
* */
public static void sort(int[] arr, int L, int R) {
int mind = (L + R)>>1;
if (L < R) {
//左边排序
sort(arr, L, mind);
//右边排序
sort(arr, mind + 1, R);
//合并排序
mergeSort(arr,L,mind,R);
}
}
public static void mergeSort(int [] arr,int L,int mind,int R){
int [] temp = new int[R-L+1];
int leftPoint = L ; // 左指针
int rightPoint = mind+1 ; // 右指针
//k标记了 while (leftPoint<=mind&&rightPoint<=R) 在这循环里面往临时数组添加元素个数或者位置的标记
int k = 0 ;
while (leftPoint<=mind&&rightPoint<=R){
//i<=mid 表示左半边的数组,下标最大可以到达的位置。限制左指针往右移的最大位置
//j<=high 表示右半边的数组,下标最大可以到达的位置,限制右指针往右移的最大位置
//比较 a[i] 与 a[j] 大小,把小的放到临时数组中并且对应的指针也要加1。再进行左右半边的比较。并且k做加1的标记 ,记录临时数组添加元素的个数
if(arr[leftPoint]<arr[rightPoint]){
temp[k++]= arr[leftPoint++];
}else {
temp[k++]= arr[rightPoint++];
}
}
// 把左边剩余的数移入数组
while (leftPoint<=mind){
temp[k++]=arr[leftPoint++];
}
// 把右边边剩余的数移入数组
while (rightPoint<=R){
temp[k++]=arr[rightPoint++];
}
// 把新数组中的数覆盖nums数组
for (int i = 0 ;i<temp.length;i++){
arr[i+L] = temp[i];
}
}
}