写在前面
- 楼主整理经典的排序算法
- 记录学习
1. 归并排序(MergeSort)
1.1 概念
归并排序利用的是分治的思想实现的,对于给定的一组数据,利用递归与分治技术将数据序列划分成为越来越小的子序列,之后对子序列排序,最后再用递归方法将排好序的子序列合并成为有序序列。合并两个子序列时,需要申请两个子序列加起来长度的内存,临时存储新的生成序列,再将新生成的序列赋值到原数组相应的位置。
1.2 算法描述
- 把长度为n的输入序列分成两个长度为n/2的子序列;
- 对这两个子序列分别采用归并排序;
- 将两个排序好的子序列合并成一个最终的排序序列。
示意图
1.3 代码演示
package com.zhuang.algorithm;
import java.util.Arrays;
/**
* @Classname MergeSort
* @Description 归并排序
* @Date 2021/6/13 15:49
* @Created by dell
*/
public class MergeSort {
public static void main(String[] args) {
int[] arr = {9, 2, 6, 3, 5, 7, 10, 11, 12};
merSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));//[2, 3, 5, 6, 7, 9, 10, 11, 12]
}
public static void merSort(int[] arr, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
//左边归并排序,使得左子序列有序
merSort(arr, left, mid);
//右边归并排序,使得右子序列有序
merSort(arr, mid + 1, right);
//合并两个子序列
merge(arr, left, mid, right);
}
}
private static void merge(int[] arr, int left, int mid, int right) {
//可以从开始就申请一个与原数组大小相同的数组,因为重复new数组会频繁申请内存
int[] temp = new int[right - left + 1];
int i = left;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= right) {
if (arr[i] < arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
while (i <= mid) {
//将左边剩余元素填充进temp中
temp[k++] = arr[i++];
}
while (j <= right) {
//将右序列剩余元素填充进temp中
temp[k++] = arr[j++];
}
//将temp中的元素全部拷贝到原数组中
for (int k2 = 0; k2 < temp.length; k2++) {
arr[k2 + left] = temp[k2];
}
}
}
1.4 算法分析
- 最佳情况:T(n) = O(n)
- 最差情况:T(n) = O(nlogn)
- 平均情况:T(n) = O(nlogn)
1.5 适用场景
归并排序在数据量比较大的时候也有较为出色的表现(效率上),其空间复杂度O(n)使得在数据量特别大的时候(例如,1千万数据)几乎不可接受。而且,考虑到有的机器内存本身就比较小,因此,采用归并排序一定要注意。
写在最后
- 学习阶段,描述不当地方,还请大家在评论区指出
- 继续加油💪
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/140721.html