个人博客:www.hellocode.top
Java知识导航:Java-Navigate
CSDN:HelloCode.
知乎:HelloCode
掘金:HelloCode
⚡如有问题,欢迎指正,一起学习~~
当谈到高效的排序算法时,归并排序是一个备受推崇的选择。归并排序是一种分治算法,它将一个大问题分解成若干个小问题,然后逐个解决这些小问题,并将它们合并成一个整体的解。
这里采用五分钟学算法大佬的图解,十分清晰
三个阶段,涉及到递归就比较难理解(个人感觉),最好配合动画好好理解理解。主要就是分解和归并(将大问题分解为小问题,再通过归并过程合并并排序)
每次随便写数组挺麻烦的,后续就都使用我写的工具类来生成随机数组了~
归并排序相对难理解一些,主要涉及到分解和归并,将待排序数组一个个拆分,直到拆分为1个1组(无需排序),接下来就是自底向上逐个合并,在合并的同时进行排序操作,最终合并好的就是有序的数组了
/**
* @author HelloCode
* @blog https://www.hellocode.top
* @date 2023年08月15日 19:33
*/
public class MergeSort {
public static void main(String[] args) {
// 生成容量为15的由100以内随机数构成的int数组(用到了自己写的一个工具类)
int[] arr = ArrayUtil.randomIntArray(15, 100);
System.out.println("原数组:" + Arrays.toString(arr));
mergeSort(arr);
System.out.println("排序后:" + Arrays.toString(arr));
}
private static void mergeSort(int[] arr) {
if (arr == null || arr.length <= 1) {
return; // 数组为空或只有一个元素,无需排序
}
// 创建临时数组(避免多次创建)
int[] temp = new int[arr.length];
// 递归入口
sort(arr, temp, 0, arr.length - 1);
}
// 拆分
private static void sort(int[] arr, int[] temp, int left, int right) {
// 递归出口
if (left >= right) {
return;
}
// 记录中间值(左边数组的末尾,+1为右边数组的起始)
int mid = left + ((right - left) >> 1);
// 开始拆分
sort(arr, temp, left, mid);
sort(arr, temp, mid + 1, right);
// 归并
merge(arr, temp, left, mid, right);
}
// 归并(排序)
private static void merge(int[] arr, int[] temp, int left, int mid, int right) {
// 记录临时数组索引
int p = left;
// 左半边起始索引
int i = left;
// 右半边起始索引
int j = mid + 1;
// 开始归并
// 两边都还有的情况
while(i <= mid && j <= right){
if(arr[i] <= arr[j]){
temp[p++] = arr[i++];
}else{
temp[p++] = arr[j++];
}
}
// 左边还有剩余的情况(直接加到临时数组末尾)
while(i <= mid){
temp[p++] = arr[i++];
}
// 右边还有剩余的情况(直接加到临时数组末尾)
while(j <= right){
temp[p++] = arr[j++];
}
// 将临时数组拷贝回原数组
for(int k = left; k <= right; k++){
arr[k] = temp[k];
}
}
}
测试:
原数组:[83, 49, 19, 75, 26, 64, 59, 60, 11, 97, 36, 41, 17, 31, 69]
排序后:[11, 17, 19, 26, 31, 36, 41, 49, 59, 60, 64, 69, 75, 83, 97]
生成随机数组的工具类:
/**
* @author HelloCode
* @blog https://www.hellocode.top
* @date 2023年08月13日 20:01
*/
public class ArrayUtil {
private static final Random RANDOM = new Random();
public static int[] randomIntArray(int capacity,int max){
// 创建capacity大小的数组(1~max)
int[] res = new int[capacity];
for(int i = 0; i < capacity; i++){
res[i] = RANDOM.nextInt(max) + 1;
}
return res;
}
}
归并排序本身是一个稳定且效率较高的排序算法,但还是有一些优化方法可以进一步提升性能:
通过分治思想,归并排序将排序问题分解为小问题,并通过合并操作将它们逐步解决,从而实现高效且稳定的排序。这使得归并排序成为计算机科学中重要的算法之一。