先上概念: [归并排序](来自百度百科)
归并排序是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
下来是代码实现和思路
/**
* merge
*/
public class Merge {
/**
* 思路: 数组前一半有序, 后一半有序, 通过分为两个子数组,
* 把子数组元素比较,小的数保存,并滑动,
* 最后将剩余子数组整体平移
* Tips:
* Tip1: 归并merge算法是稳定的算法, 关注这个条件arr[i] <= arr[j],
* 如果不带=, 会倒换相同元素的顺序, 使算法不稳定.
*/
public static int[] merge(int[] arr) {
int[] tempArr = new int[arr.length];
int i = 0;
int mid = arr.length / 2;
int j = mid + 1;
int k = 0;
while (i <= mid && j < arr.length) {
tempArr[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
}
while (i <= mid) {
tempArr[k++] = arr[i++];
}
while (j < arr.length) {
tempArr[k++] = arr[j++];
}
return tempArr;
}
public static void main(String[] args) {
int[] arr = {1, 4, 7, 8, 3, 6, 9};
// int[] arr = {1, 4, 7, 3, 6, 9};
int[] sortedArr = Merge.merge(arr);
for (int item : sortedArr) {
System.out.print(item + "\t");
}
}
/**
* 归并排序算法
*/
public class MergeSortTestv2 {
/**
* 思路: 数组前一半有序, 后一半有序, 通过分为两个子数组,
* 把子数组元素比较,小的数保存,并滑动,
* 最后将剩余子数组整体平移
* Tips:
* Tip1: 归并merge算法是稳定的算法, 关注这个条件arr[i] <= arr[j],
* 如果不带=, 会倒换相同元素的顺序, 使算法不稳定.
* Tip2: 关注边界
*
* @param leftPointer [me
* @param rightPointer: mid + 1; mid = (leftPointer + rightPointer)/2
* @param rightBound: me]
*/
public static void merge(int[] arr, int leftPointer, int rightPointer, int rightBound) {
int[] tempArr = new int[rightBound - leftPointer + 1];
int i = leftPointer;
int mid = rightPointer - 1;
int j = rightPointer;
int k = 0;
while (i <= mid && j <= rightBound) {
tempArr[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
}
while (i <= mid) {
tempArr[k++] = arr[i++];
}
while (j <= rightBound) {
tempArr[k++] = arr[j++];
}
for (int m = 0; m < tempArr.length; m++) {
arr[leftPointer + m] = tempArr[m];
}
}
/**
* 归并排序主算法: 思路: 分半, 排左边, 排右边(采用递归), 最终merge合并
*
* @param arr 数组
* @param left 左边界
* @param right 右边界
*/
public static void mergeSort(int[] arr, int left, int right) {
if (left == right) {
return;
}
// 注意mid不要采用加法形式,防止int越界
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid + 1, right);
}
public static void main(String[] args) {
//int[] arr={0, 1, 2, 3, 4, 5, 6};
// int[] arr = {1, 4, 7, 8, 3, 6, 9};
// subarr = {4, 7, 8, 3, 6};
int[] arr = {1, 4, 7, 3, 6, 9};
MergeSortTestv2.mergeSort(arr, 0, arr.length - 1);
for (int item : arr) {
System.out.print(item + "\t");
}
}
}
最后是马士兵在b站的视频讲解(part1, part2)
马士兵说:归并排序,java对象排序的默认算法_哔哩哔哩_bilibili同学们好,我是马士兵,本视频是系列课程视频。欢迎同学们关注我,依次跟我学习算法这门内功知识。同学们关注、转发、抽藏,或者进我讨论组学习。讨论组怎么进,看个人主页!复习递归概念,复习之前会用到方法在内存中的执行过程。递归是一个方法在自身的内部执行过程之中执行自身。实际中的执行过程是什么样,视频过程中会深入浅出的讲到。https://www.bilibili.com/video/BV1yb411p7f1?spm_id_from=333.999.0.0马士兵说:归并排序(二),程序是调出来的,请大家一定要学会修复BUG_哔哩哔哩_bilibili同学们好,我是马士兵!了解更多技术知识,关注“马士兵说”进粉丝讨论组,看个人主页即可找联系方式进来!。今天讲的小内容是《归并排序》二:写完了一个归并的方法,这个归并方法是在数组两个半截数组,在已经排好顺序的情况下,怎么合并到一起!另外讲初始的算法进行改造,让这个数组变得更加灵活,另外大家也要学会修复BUG,调试bug!
https://www.bilibili.com/video/BV1Kb411W7ev?spm_id_from=333.999.0.0