算法导论系列笔记之线性时间排序

线性时间排序

速度取决于计算模型【哪些操作是被允许的】

比较排序的算法模型

在模型中只能进行两两之间的大小比较来决定顺序

  • 快速排序
  • 归并排序
  • 插入排序
  • 堆排序

定理

比较排序的算法速度不会超过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
  • 缓存要求高,实际操作并没有那么快,除非数都很小
发布了28 篇原创文章 · 获赞 1 · 访问量 1727

猜你喜欢

转载自blog.csdn.net/doordiev/article/details/104311182
今日推荐