一. 归并排序
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法 的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使 每个子序列有序,再使子序列段间有序。
若将两个有序表合并成一个有序表,称为 2-路归并,与之对应的还有多路归 并。 对于给定的一组数据,利用递归与分治技术将数据序列划分成为越来越小的 半子表,在对半子表排序后,再用递归方法将排好序的半子表合并成为越来越大 的有序序列。
为了提升性能,有时我们在半子表的个数小于某个数(比如 15)的情况下, 对半子表的排序采用其他排序算法,比如插入排序。
二. 归并排序流程分析
三. 程序实现
public static void main(String[] args) {
int[] arr = {20, 92, 60, 50, 40, 30, 70, 80, 100, 90};
int[] sort = sort(arr);
System.out.println(Arrays.toString(sort));
}
// 使用递归进行处理 切分数组,把数组切割成最小的粒度
private static int[] sort(int[] array){
//最小颗粒的排序可以使用其他排序方法进行排序,因为使用的是递归计算排序的数据很多的话
//会有大量的方法进栈出栈,对内存资源的消耗比较大,耗时就会比增加
if (array.length < 2){
return array;
}
if (array.length == 2){
if (array[0] > array[1]){
int temp = array[1];
array[1] = array[0];
array[0] = temp;
}
return array;
}
// 把数组分成两部分,持续分割,直到分割到符合自己设定的最小组合
int middle = array.length / 2;
int[] left = Arrays.copyOfRange(array, 0, middle);
int[] right = Arrays.copyOfRange(array, middle, array.length);
return mergeArray(sort(left), sort(right));
}
/**
* @author charles
* @createTime 2020/6/13 12:57
* @desc 合并俩个已经排好顺序的数组
*/
private static int[] mergeArray(int[] left, int[] right) {
// 初始化一个数组存放结果
int[] resultArray = new int[left.length + right.length];
for (int i = 0, leftIndex = 0 , rightIndex = 0; i < resultArray.length; i++) {
// 当 left 数组数据都已经排序进结果集中后,取右边的数组 right
if (leftIndex >= left.length){
resultArray[i] = right[rightIndex ++];
} else if (rightIndex >= right.length) {
// 当right 中的数组数据都已经排序进结果集中后, 取左边的数组 left
resultArray[i] = left[leftIndex ++];
} else if (left[leftIndex] > right[rightIndex]){
// 左边的数据大于右边的数据 升序排序取最小值
resultArray[i] = right[rightIndex ++];
} else {
// 左边的数据小于右边的数据 升序排序取最小值
resultArray[i] = left[leftIndex ++];
}
}
return resultArray;
}