@[TOC](【算法复习2】时间复杂度 O[nlogn]快速排序归并排序分析)
归并排序
分治思想
- 分解
递归 对半分 直到 分成 1个 - 合并
两个 元素 排序后 合并 依次类推直到合成一个大数组
分治是一种编程思想
递归是一种编程技巧
分治一般由递归来实现
稳定性
归并排序 稳定 主要看 子数组 排序后 merge 合并的函数如何执行
可以按先后顺序 合并 merge 函数 保证算法的稳定性
递归转递推
不仅递归求解的问题可以写成递推公式,
递归代码的时间复杂度也可以写成递推公式
时间复杂度很稳定
时间复杂度是非常稳定
不管 数据之前顺序如何 都要重新拍一遍
不管是最好情况、最坏情况,还是平均情况,时间复杂度都是 O(nlogn)
归并致命的空间复杂度
每次合并都要频繁的申请新的内存空间 存储合并后的数据
虽然最大也就是 申请 元素个数个大小 n个大小 而且用完就释放
但是 频繁的 申请 释放 也会造成不小的资源开销 复制移动 更新
因为用完就释放所以
空间复杂度是 O(n)
虽然归并排序稳定但是,
归并排序不是原地排序算法,所以还是没有快速排序那样风靡各大技术 的底层排序
快速排序
快排 规则
- 排序数组中下标从 p 到 r 之间的一组数据,我们选择 p 到 r 之间的任意一个数据作为 pivot(分区点)
- 遍历 p 到 r 之间的数据,将小于 pivot 的放到左边,将大于 pivot 的放到右边,将 pivot 放到中间
- 递归排序下标从 p 到 q-1 之间的数据和下标从 q+1 到 r 之间的数据,直到区间缩小为 1,就说明所有的数据都有序了。
原地排序 超越归并缺点
原地分区函数的实现思路非常巧妙
用交换代替插入
节约了时间和内存资源 但是 破坏了稳定性
老师画的图 一目了然
归并由上到下
快排由下到上
快排性能分析
两个极端情况下的时间复杂度
- 分区极其均衡 O(1)
- 分区极其不均衡 O(n2)
总结
- 理解归并排序的重点是理解递推公式和 merge() 合并函数
- 同理,理解快排的重点也是理解递推公式,还有 partition() 分区函数
- 归并排序算法是一种在任何情况下时间复杂度都比较稳定的排序算法,这也使它存在致命的缺点,即归并排序不是原地排序算法,空间复杂度比较高,是 O(n)
- 可以通过合理地选择 pivot 来避免速排序算法时间复杂度退化到 O(n2)
全部评论
(0) 回帖