思路
分治法 将数组分成A、B两组,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。如何让这二组组内数据有序了?
可以将A,B组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序。
代码
1 | //将两个有序数组合并成一个有序数组 |
时间复杂度
由于归并排序是先将数组分成两部分,将两部分分别排序后,再合并。假设n个元素排序的时间是T(n),而两部分分别排序的时间是T(n/2),合并的复杂度是cn;因此:
\[T(n) = 2T(n/2) + cn\]
再解释一下\(T(n) = 2T(n/2) + cn\) 这个东西,$ 2T(n/2)$ 是下一层带来的代价,\(cn\) 是本层带来的代价。因此我们画一颗递归树,树的【每层表示本层所消耗的代价】,如下图所示:
- 第一行cn表示当前层消耗的代价
- 第二行两个T(n/2)代表下一层消耗的代价
将这个递归树再往下拓展一层,我们得到:
我们再进行扩展:
我们看到,完全扩展了的递归树具有\(logn + 1\) 层,其中每层的代价都是\(cn\) 。因此总的代价为【每一层的代价之和】:
\[cn (log n + 1) = cnlogn + cn = O(nlogn)\]
- 最坏情况\(O(n\log(n))\)
- 平均情况\(O(n\log(n))\)