归并排序同快排一样也体现了分治的思想,归并排序把数组元素按照下标分成两组,然后分别对每一组进行排序,排序完成后将两个部分合并到一起。
过程大致如下图,假设柱子为小朋友,我们的目标的是小朋友按照身高进行排序,如果使用归并排序,首先把小朋友分成两队,然后对每一对按身高进行排序,排完序后两两比较身高,谁的身高矮谁先通过门,最后两个队伍合并到一起排序完成。
代码实现:
public class 归并排序 {
public static void main(String[] args) {
int[] arr = {2,14,42,3,4,7,16,8,10,125,6,60};
mergeSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
/**
* 归并排序
* @param arr
* @param p
* @param r
*/
static void mergeSort(int[] arr,int p,int r) {
if(p<r) {
int mid = p + ((r-p)>>1);
mergeSort(arr,p,mid);
mergeSort(arr,mid+1,r);
merge(arr,p,mid,r);
}
}
/**
* 合并排序元素
* @param arr 数组
* @param p
* @param mid
* @param r
*/
static void merge(int[] arr, int p, int mid, int r) {
//把A中的数拷贝到helper中
int[] helper = Arrays.copyOf(arr, arr.length);
//lefth的p为helper数组的头指针,current的p为原数组的头指针
int left = p,right = mid+1,current = p;
while(left<=mid && right <= r) {
if(helper[left]<=helper[right]) {
arr[current] = helper[left];
current++;
left++;
}else {
arr[current] = helper[right];
current++;
right++;
}
}
while(left<=mid) {
arr[current] = helper[left];
current++;
left++;
}
}
}