线性时间排序
- 以下为本人整理课程笔记
- 课程地址:b站搬运
- github:还有除了算法导论外一些基础知识的笔记
- 我们能做到的排序有多快?
速度取决于计算模型【哪些操作是被允许的】
比较排序的算法模型
在模型中只能进行两两之间的大小比较来决定顺序
- 快速排序
- 归并排序
- 插入排序
- 堆排序
定理
比较排序的算法速度不会超过
nlgn
决策树
-
举例3个数进行比较排序的决策树
-
每一个内部节点都会有一个下标为i:j标记,左孩子为小于等于,右孩子为大于
-
每一个叶结点表示一个排序结果,其中有一个是正确的特定排序
决策树模型
- 构建可以接收n个数进行比较的一个决策树【至少一个
- 就是把算法中可能的结果都列出来
- 树的叶子结点与n的阶乘有关,树的大小与n的指数有关
- 运行时间与树的高度
- 以此去证明比较排序的下界为
nlgn
证明
n!<=2^h
【lgn为单调递增函数h>=lg(n!)
确定性算法:它执行的每一步都是完全正确的
- 如果是随机算法,就会得到不止一个树,而是一个概率分布的多种
线性时间内完成
计数排序
- 假定要排序的是n个整数,每个整数都在1到k的范围内,需要辅助存储序列
伪代码
COUNTING-SORT(A,B,k)
let C[0…k] be a new array //记录各个数出现的频率
for i=0 to k
C[i] = 0
for j=1 to A.length
C[A[j]] = C[A[j]] +1
for i=1 to k
C[i] = C[i]+C[i-1]
for j=A.length downto 1
B[C[A[j]]] = A[j]
C[A[j]] = C[A[j]]-1
- 时间代价为Θ(k+n)
重要性质
- 稳定性:保证了相等元素的顺序
基数排序
线性时间内处理大规模数据
- 打孔卡片
想法
-
直观感受看:从最高有效位进行排序,然后对得到的每个容器递归进行排序,最后再把所有结果合并起来。
-
正确做法:先按最低有效位进行排序【必须是稳定排序】,然后把所有卡片合并成一叠
分析
- 对每一位的数字使用计数排序,Θ(n+k)
- 假设有n位二进制数,每个整数设为b比特长,则数的大小在(1~2^b-1)
- 把每个整数拆分位b/r位数字,每个数字为r比特长
- 时间为Θ((b/r)(n+2^r))
- 求导确定r的最小值,或通过分析增长速度,r = lgn
- 把每个整数拆分位b/r位数字,每个数字为r比特长
- 时间为Θ((b/r)(n+2^r))
- 求导确定r的最小值,或通过分析增长速度,r = lgn
- 缓存要求高,实际操作并没有那么快,除非数都很小
来源:CSDN
作者:doordiey
链接:https://blog.csdn.net/doordiev/article/details/104311182