归并排序
首先摘抄网上的几个动画效果图:
图一:
图二:
图3:
// 归并排序,是创建在归并操作上的一种有效的排序算法。
// 算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。
// 归并排序速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。
// 大体思路:
// 1.创建临时数组,大小为 两个相比较的序列之和
// 2.创建两个指针,分别为两个序列的 开始位置;再创建一个指针只想新数组开始位置
// 3.比较两个指针所指向的两个元素的大小,取小值元素 添加到新数组中,同时小元素指针下移,新数组元素指针下移
// 4.重复3步骤,直到某一个序列的指针到尾部
// 5.将剩余的序列的元素,直接copy到新数组尾部
// 6.更新原数组和新数组的相对位置
// 注:两个比较的序列,经过层层比较,每一个序列的元素相对大小位置已经确定好了,也就是每个序列已经排好位置了
/**
* @param nums 原数组
* @param start 开始坐标
* @param end 结束坐标
*/
public void mergeSoft(int[] nums, int start, int end) {
if (start >= end) return;
// 获取分割点
int divider = (end + start) / 2;
// 区间 start - divider; divider+1 - end
if (divider > start) {
// 说明 左边还存在,继续分离
mergeSoft(nums, start, divider);
}
if (end > divider + 1) {
// 说明 右边还存在,继续分离
mergeSoft(nums, divider + 1, end);
}
// 比较两个已经排好位置的 序列
//临时数组长度,存储 改变之后的信息
int[] tem = new int[end - start + 1];
// 两个数组之间进行比较
// start-divider,divider+1-end
int k = 0; // 新数组指针
int left = start; // 左序列指针
int right = divider + 1; // 右序列指针
// 比较并给新数组赋值较小的值,并移动相应的指针
while (left <= divider && right <= end) {
// 一定要小于等于,要不不能保证相对次序了
if (nums[left] <= nums[right]) {
tem[k] = nums[left];
left++;
} else {
tem[k] = nums[right];
right++;
}
k++;
}
// 判断两边数组是否有剩余
while (left <= divider || right <= end) {
if (left <= divider) {
// 左边剩余
tem[k] = nums[left];
left++;
}
if (right <= end) {
tem[k] = nums[right];
right++;
}
k++;
}
// tem 赋值到nums中
System.arraycopy(tem, 0, nums, start, tem.length);
}
// 开始调用:
// mergeSoft(nums, 0, nums.length - 1);
参考资料:
排序算法之归并排序https://zhuanlan.zhihu.com/p/124356219
java 常见的几种排序方法https://www.cnblogs.com/ll409546297/p/10956960.html