归并排序
整体思想
分治(divide-and-conquer)
具体步骤
- sort 排序 拆分待排序数组,当拆分成数组元素只有一个的时候 即 {1} 或者{47} 默认为已排序
- merge 合并 将排好序的数组按照大小存储在temp临时数组中,扫描左右两数组并将数字从小到大放入temp数组中, 但是扫描过程可能扫描完左数组就退出,或者扫描完右数组就退出,所以我们需要将剩余元素直接填充到temp数组中。 例如 {38,49} {65,97} 进行合并过程中,38,49依次进入temp数组,而右数组的数字仍未操作过,所以需要进一步判断。
具体代码 Sort
public static int[] sort(int[] a,int low,int high){
//每次将数组拆分一半, 直到low==high
int mid = (low+high)/2;
if (low<high){
//左边数组排序
sort(a,low,mid);
//右边数组排序
sort(a,mid+1,high);
//合并
merge(a,low,mid,high);
}
return a;
}
具体代码 Merge
public static void merge(int[] a, int low, int mid, int high) {
//临时数组存储排序元素
int[] temp = new int[high-low+1];
int i = low;
int j = mid+1;
int k = 0;
while(i<=mid && j<=high){
if (a[i]<a[j]){
temp[k++] = a[i++];
}else{
temp[k++] = a[j++];
}
}
while (i<=mid){
temp[k++] = a[i++];
}
while(j<=high){
temp[k++] = a[j++];
}
//从low当前位置开始
//将temp数组中k个已排好序元素放入target目标数组a中
for (int x= 0;x<k;x++){
a[low+x] = temp[x];
}
}
案例:
int[] a = {44,2,77,34,12,87,14,1};
排序结果
[1, 2, 12, 14, 34, 44, 77, 87]
可改进部分
在排序sort方法中提前声明temp临时数组变量,防止递归调用中重复创建对象,造成资源浪费以及占用。