一、算法简介
归并排序,是创建在归并操作上的一种有效的排序算法。算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。归并排序思路简单,速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。
二、算法描述
归并排序是用分治思想,分治模式在每一层递归上有三个步骤:
- 分解(Divide):将n个元素分成个含n/2个元素的子序列。
- 解决(Conquer):用合并排序法对两个子序列递归的排序。
- 合并(Combine):合并两个已排序的子序列已得到排序结果。
三、算法步骤
-
首先将数组拆分成两部分
-
对这两部分分别递归排序
• 元素个数大于1,继续拆分
• 只有一个元素时无需排序,结束递归 -
在对有序数组进行两两合并
-
合并操作:
- 寻找两个有序数组的最小值
• 即两个数组最小值中较小的那个
• 放入合并后数组的第一位 - 寻找两个数组第2小的值
- 寻找两个数组第3小的值
- 寻找两个数组第4小的值
- 依次进行直到结束
- 寻找两个有序数组的最小值
四、算法实现
public static int[] mergeSort(int[] arr) {
if (arr.length < 2) return arr;
//计算中间位置
int mid = arr.length / 2;
//分解为左右两部分,分别排序
int[] left = Arrays.copyOfRange(arr, 0, mid);
left = mergeSort(left);
int[] right=Arrays.copyOfRange(arr,mid,arr.length);
right = mergeSort(right);
//合并两个排序后的数组为一个数组
return merge(left, right);
}
private static int[] merge(int[] l, int[] r) {
int[] result = new int[l.length + r.length];
int lIndex = 0;
int rIndex = 0;
for (int i = 0; i < result.length; i++) {
if (lIndex < l.length && rIndex < r.length) {
if (l[lIndex] <= r[rIndex]) {
result[i] = l[lIndex++];
} else {
result[i] = r[rIndex++];
}
} else if (lIndex >= l.length) {
result[i] = r[rIndex++];
} else {
result[i] = l[lIndex++];
}
}
return result;
}