归并排序
- 归并排序的思想就是不断的将当前序列平均分割成2个子序列,直到不能再分割(即此时序列中只剩下一个元素)
- 不断的将两个子序列进行合并,变成一个有序序列,直到最终只剩下一个有序序列
上述两个图就代表了归并排序的过程。即我们总是在归与并,当然,这其中也体现了分治和递归的思想。在后面,我会详细的介绍分治与递归!
- 接下来解释合并操作
如上图所示,我们备份出左边数组,直接让左边数组的第一个元素即leftArray[li]与右边数组array[ri]进行比较,将小的元素存放到array[ai]位置,并且同时移动ai指针和较小元素那个数组的指针。
接下来我们考虑终止情况,如果右边先结束,即代表此时左边还没移动的元素都比右边要大,我们直接将左边的元素照搬过来即可。
如果左边先结束,此时我们什么操作都不需要进行。
代码如下所示
1 | public class MergeSort { |
- 下面我们来考虑归并排序的时间复杂度
T(n)=2*T(n/2)+O(n) (我们将合并操作理解为遍历左边数组和遍历右边数组,并且合并在一起,为O(n)复杂度)
T(1)=O(1)
T(n)/n=T(n/2)/(n/2)+O(1) -> 令S(n)=T(n)/n
即S(n)=S(n/2)+O(1) ->S(n)=s(n/4)+O(2) ->S(4)=S(n/8)+O(3)
一直递推,此时S(n)=S(n/2^k)+O(k)=S(1)+O(logn) 将上述代入得,S(n)=O(logn) 即此时T(n)=O(nlogn)
- 即我们推出归并排序的时间复杂度为O(nlogn) ,相对于我们之前所讲的冒泡排序,选择排序,插入排序,有很明显的提升!