排序
【内部排序】
冒泡排序
- 实现简单,可适用于链表,可以添加flag标记,最好O(n),最坏O(n^2)
- 稳定
直接插入排序
- 最好O(n),最坏O(n^2)
- 稳定
- 插入排序与冒泡排序 T(N,I)=O(N+I),其中I为逆序对个数
- 定理:任意N个不同元素平均逆序对个数是N(N-1)/4
- 启发:每次交换消除多个逆序对(跳着交换)==》希尔排序
希尔排序
- 原始增量 D=【N/2】(向下取整) 平均时间复杂度O(N^2)
- 增量需要互质!
- 算法简单,复杂度分析极其困难
- 不稳定
堆排序
- 选择排序进化版(简单选择排序不稳定)
- O(NlogN) 额外空间O(N)
- 不需要额外空间的最大堆,根节点与最后节点作交换
- O(2NlogN)-O(NloglogN) 可能不如希尔排序,常数很大
- 不稳定
归并排序
- O(N/2+N/2)+O(N),O(N)额外空间
- 用一个全局的额外空间
- 递归算法与非递归算法
- 稳定
- 在外部排序非常有用
快速排序
- 思想是”分而治之“
- 主元怎么选?直接选A[0]–顺序凉凉;随机选取开销大;取中位数合算(中间元素和中位数😔)
- 独立子集怎么划分?主元在子集划分完成后被放在了正确的位置上
- 碰到相等元素怎么办?交换–O(NlogN),忽略–O(N^2)。还是老老实实交换吧
- 小规模数据,直接采用简单插入排序更快
- 不稳定
表排序
- 间接排序
- 交换指针数组(下标)
- N个数字的排列由若干个独立的环组成
基数排序
- 桶排序–数多桶少
- 次位优先(LSD,Least Significant Digit)
- 根据位数选取 O(P(N+B)) P是位数,B是桶数 额外空间O(N+B)
- ”多关键字“排序 主位优先(MSD,Most Significant Digit)不如次位优先,排完有序放入桶中分类
- 稳定
【外部排序】
(多路)归并排序
当内存小于外存,可以先排出几个有序序列,再进行归并