前言
归并排序是一个相当快速的算法,其时间复杂度稳定在O(n*logn),在面试中被问到的频率也挺高的,今天就来介绍一下这个排序算法
手撕算法 - 排序系列
手撕面试题算法<排序>(1)—— 冒泡排序及其优化实现
手撕面试题算法<排序>(2)—— 选择排序
手撕面试题算法<排序>(3)—— 插入排序及其优化实现
手撕面试题算法<排序>(3.5)—— 希尔排序
手撕面试题算法<排序>(4)—— 归并排序
手撕面试题算法<排序>(5)—— 快速排序以及快排为什么快
手撕面试题算法<排序>(6)—— 堆 & 堆排序
手撕面试题算法<排序>(7)—— 箱排序 & 基数排序
源码
归并排序
思想
在归并排序中体现的是分治的思想,其将一个数组一分为二,二分为四,直到不能再分——将难以处理的大问题拆分成容易处理的小问题,最后再将排序完毕的数组合并在一起,完成数组的排序
时间复杂度
将一个数组对半拆分处理的时间复杂度是O(logn)
例,对一个长度为n的数组进行递归拆分:
- 第1次递归,将n个数拆分为2个子区间,每个子区间长度为n/2
- 第2次递归,将n个数拆分为4个子区间,每个子区间长度为n/4
- 第3次递归,将n个数拆分为8个子区间,每个子区间长度为n/8
… - 第logn次递归,将n个数拆分为n个子区间,每个子区间长度为1
而每次对子区间的排序的次数为:
- 第一次递归后的排序,遍历2个长度为n/2的数组,O(n)
- 第二次递归后的排序,遍历4个长度为n/4的数组,O(n)
- …
所以归并排序总共需要走logn次O(n)的操作,的时间复杂度为 O(n*logn)
实现
1. 核心 - 数组的拆分
我们使用递归来将数组进行拆分
通过传入的数组,以及区间[L, R],来对半划分数组,并将划分后的L, R记录下来进行下一次递归,直到 L >= R
private static void sort(int[]