JAVA十大排序算法之归并排序详解
目录
- 归并排序
- 怎么分
- 怎么治
- 代码实现
- 时间复杂度
- 算法稳定性
- 总结
归并排序 归并,指合并,合在一起。归并排序(Merge Sort)是建立在归并操作上的一种排序算法。其主要思想是分而治之。什么是分而治之?分而治之就是将一个复杂的计算,按照设定的阈值进行分解成多个计算,然后将各个计算结果进行汇总。即“分”就是把一个大的通过递归拆成若干个小的,“治”就是将分后的结果在合在一起。
若将两个有序集合并成一个有序表,称为2-路归并,与之对应的还有多路归并。
文章图片
【JAVA十大排序算法之归并排序详解】
怎么分
- 对于排序最好的情况来讲,就是只有两个元素,这时候比较大小就很简单,但是还是需要比较
- 如果拆分为左右各一个,无需比较即是有序的。
怎么治
借助一个辅助空数组,把左右两边的数组按照大小比较,按顺序放入辅助数组中即可。
以下面两个有序数组为例:
文章图片
代码实现
public class MergeSort {public static final int[] ARRAY = {8, 5, 6, 4, 3, 1, 7, 2}; public static int[] sort(int[] array) {if (array.length < 2) return array; int mid = array.length / 2; //分成2组int[] left = Arrays.copyOfRange(array, 0, mid); int[] right = Arrays.copyOfRange(array, mid, array.length); //递归拆分return merge(sort(left), sort(right)); }//治---合并public static int[] merge(int[] left, int[] right) {int[] result = new int[left.length + right.length]; //i代表左边数组的索引,j代表右边for (int index = 0, i = 0, j = 0; index < result.length; index++) {if (i >= left.length) {//说明左侧的数据已经全部取完,取右边的数据result[index] = right[j++]; } else if (j >= right.length) {//说明右侧的数据已经全部取完,取左边的数据result[index] = left[i++]; } else if (left[i] > right[j]) {//左边大于右边,取右边的int a = right[j++]; result[index] = a; } else {//右边大于左边,取左边的result[index] = left[i++]; }}return result; }public static void print(int[] array) {for (int i : array) {System.out.print(i + ""); }System.out.println(""); }public static void main(String[] args) {print(ARRAY); System.out.println("============================================"); print(sort(ARRAY)); }}
时间复杂度
归并排序方法就是把一组n个数的序列,折半分为两个序列,然后再将这两个序列再分,一直分下去,直到分为n个长度为1的序列。然后两两按大小归并。如此反复,直到最后形成包含n个数的一个数组。
归并排序总时间 = 分解时间 + 子序列排好序时间 + 合并时间无论每个序列有多少数都是折中分解,所以分解时间是个常数,可以忽略不计,则:
归并排序总时间 = 子序列排好序时间 + 合并时间假设处理的数据规模大小为 n,运行时间设为:T(n),则T(n) = n,当 n = 1时,T(1) = 1
由于在合并时,两个子序列已经排好序,所以在合并的时候只需要 if 判断即可,所以n个数比较,合并的时间复杂度为 n。
- 将 n 个数的序列,分为两个 n/2 的序列,则:T(n) = 2T(n/2) + n
- 将 n/2 个数的序列,分为四个 n/4 的序列,则:T(n) = 4T(n/4) + 2n
- 将 n/4 个数的序列,分为八个 n/8 的序列,则:T(n) = 8T(n/8) + 3n
- …
- 将 n/2k 个数的序列,分为2k个 n/2k 的序列,则:T(n) = 2kT(n/2k) + kn
使用大O表示法,去掉常数项 n,省略底数 2,则归并排序的时间复杂度为:O(nlogn)
算法稳定性
从原理分析和代码可以看出,为在合并的时候,如果相等,选择前面的元素到辅助数组,所以归并排序是稳定的。
总结 本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 事件代理
- Java|Java OpenCV图像处理之SIFT角点检测详解
- java中如何实现重建二叉树
- 数组常用方法一
- 【Hadoop踩雷】Mac下安装Hadoop3以及Java版本问题
- 一个选择排序算法
- Java|Java基础——数组
- RxJava|RxJava 在Android项目中的使用(一)
- java之static、static|java之static、static final、final的区别与应用