归并排序的时间复杂度任何情况下都是 O(nlogn),看起来非常优秀。(待会儿你会发现,即便是快速排序,最坏情况下,时间复杂度也是 O(n^2)。)但是,归并排序并没有像快排那样,应用广泛,这是为什么呢?因为它有一个致命的“弱点”,那就是归并排序不是原地排序算法。
这是因为归并排序的合并函数,在合并两个有序数组为一个有序数组时,需要借助额外的存储空间。这一点你应该很容易理解。那我现在问你,归并排序的空间复杂度到底是多少呢?是 O(n),还是 O(nlogn),应该如何分析呢?
如果我们继续按照分析递归时间复杂度的方法,通过递推公式来求解,那整个归并过程需要的空间复杂度就是 O(nlogn)。不过,类似分析时间复杂度那样来分析空间复杂度,这个思路对吗?
实际上,递归代码的空间复杂度并不能像时间复杂度那样累加。刚刚我们忘记了最重要的一点,那就是,尽管每次合并操作都需要申请额外的内存空间,但在合并完成之后,临时开辟的内存空间就被释放掉了。在任意时刻,CPU 只会有一个函数在执行,也就只会有一个临时的内存空间在使用。临时内存空间最大也不会超过 n 个数据的大小,所以空间复杂度是 O(n)。
思考
- 如果数组元素个数n,归并排序过程需要多少个临时数组呢?
2+4+8+....+n/2=?
- 归并排序的空间复杂度为何不能累加?
- 归并排序为何需要临时数组?
合并的时候暂存元素,为何不能原位排序,因为需要的临时数组不止一个
- 归并排序的排序是在拆分还是在合并时进行的?
总结
- 归并排序的空间复杂度是
O(n) 归并排序应用不如快排广泛,因为需要更多的内存空间- 递归代码的
空间复杂度并不能像时间复杂度那样累加 归并排序的排序是在每一次合并时进行的,也就是说每个临时数组最终都是有序的
本文详细探讨了归并排序的空间复杂度,指出其为O(n),并解释了为何它不像快速排序那样广泛使用,主要由于其需要额外的存储空间。文章还说明了递归代码空间复杂度分析的误区,并强调归并排序的排序过程主要在合并阶段进行。
740

被折叠的 条评论
为什么被折叠?



