简单分析:
归并排序是典型的用分治思想解决问题的算法, 其基本思想是: 有两个有序数组,从两个数组首端开始比较。将较大或较小的元素加入一个空数组中,同时在原数组中删除。剩下的元素如此重复。最后就将两个有序数组合并成一个有序数组了。这样的过程成为归并。
与分治法结合在一起来考虑。如果不断递归拆分数组,直到拆分到最后只有两个元素了,也就是说把一个数组分成两边,一边只有一个元素,这是两边自然是有序的,满足有序归并的要求
实现思路:
- 1、先按归并排序原理实现数组的两部分合并。
- 2、通过递归调用拆分数组到单个元素级,再同时递归合并。
完整代码
package myFunction;
public class MergeSort2 {
//用于存放中间过程的数组
private int arrCopy[];
public void sort(int arr[]){
this.arrCopy = new int[arr.length];
//这里的left和right变量是数组的两个指针,指示数组两边,再计算出中间指针,便可以将数组一分为二。
int left = 0,
right = arr.length-1;
//调用拆分方法
cut(arr,left,right);
arrCopy = null;
}
private void cut(int[] arr, int left, int right) {
if(left < right){
int canter = left + (right - left) / 2,
begin = left,
end = right;
cut(arr,begin,canter);
cut(arr,canter+1,end);
//前面可以看做是拆分数组,这里调用的方法可以看做合并数组
merge(arr,left,canter,right);
}
}
//将元素归并
private void merge(int arr[],int left,int canter,int right) {
int canterCopy = canter+1,
leftCopy = left,
i = left;//指示归并的起始下标位,就是对比后的元素从哪开始放
while(leftCopy <= canter && canterCopy <= right){
if(arr[leftCopy] <= arr[canterCopy]){
arrCopy[i++] = arr[leftCopy++];
}else{
arrCopy[i++] = arr[canterCopy++];
}
}
//如果数组的某一边有剩余元素,就把它们全部添加到中间数组。
while(leftCopy <= canter){
arrCopy[i++] = arr[leftCopy++];
}
while(canterCopy <= right){
arrCopy[i++] = arr[canterCopy++];
}
//将数组copy回原数组。不然下次归并的数组就不是有序的了
for(int j = left; j <= right;j++){
arr[j] = arrCopy[j];
}
}
}