归并排序
要点:
- 基于分治的思想,将需要比较的数组分为左右两部分。
- 自顶向下进行分组,知道lo >= hi时,开始递归出栈。
- 将出栈后的数组依次进行递归,借助一个辅助数组aux对数组结果临时储存
- 归并操作
- 从开头和中间两个位置向左遍历
- 当左半部分已经到头,只须将右半部分辅助数组的数据赋值给原数组的对应位置
- 右半部分到头同理
- 当左半部分的值大于右半部分,则用右半部分的值进行赋值;右半部分同理
- 这样保证归并后的数组,左半部分始终是较小值;而右半部分始终是较大值
代码实现
// 根据实际的数组安排其大小
int[] aux;
public static void sort(int[] arr, int lo, int hi){
if(lo >= hi) return;
int mid = (lo + hi) / 2;
// 对两部分分别进行排序
sort(arr, lo, mid);
sort(arr, mid+1, hi);
merge(arr, lo, mid, hi);
}
public static void merge(int[] arr, int lo, int mid, int hi){
//注意两个都是从左至右遍历,所以j从mid+1开始,一直遍历到h结束
int i = lo, j = mid + 1;
// 复制数组
for(int k = lo; k <= hi; k++)
aux[k] = arr[k];
for(int k = lo; k <= hi; k++){
// 左边已经到头了
if(i > mid) arr[k] = aux[j++];
else if(j > hi) arr[k] = aux[i++];
// 如果右边的比左边小,则交换位置
else if(aux[i] > aux[j]) arr[k] = aux[j++];
else arr[k] = aux[i++];
}
}