当前课程知识点:数据结构(下) > 第十二章 排序 > (b3)选取:通用算法 > 12b3-3: linearSelect:算法
我们接下来将要介绍的这个选取算法
就是在刚才quickselect算法的基础上
进行的改进
因为这个算法即便在最还情况下
也只需渐进的线性时间
因此我们也称之为linearselect
这个算法需要用到一个常数Q
它的数值不大
我们稍候就会具体来确定它的取值
这个linearselect的算法
将以递归形式给出
因此我们首先需要准备好递归基
也就是当问题的规模已经足够小时
我们就不妨调用任何一种
平凡的选取算法
接下来我们需要将整个数据集
均匀的切分为若干组
每一组依然是一个随机的序列
它们的规模都统一取作
刚才引入的那个常数Q
如此我们将得到N除以Q个子序列
接下来对于每一个这样的子序列
我们都分别对它们进行排序
没错 排序
而且在这里
你可以不必过于在意排序的效率
比如可以直接采用插入排序算法
而在经过如此排序之后
我们也就可以直接得到
每一个子序列所对应的中位数
既然总共有N除Q个子序列
所以这里中位数也总共应该有
N除以Q个
接下来我们再从所有这些中位数中
去找到它们的中位数
也就是中位数的中位数
median of the medians
具体如何来找到呢
通过递归
也就是调用linearselect的算法本身
我们将这个中位数的中位数
记作大写的M
接下来我们就需要
以这个中位数的中位数为基准
对整个数据集中的所有元素
进行分类
具体来说所有小于M的元素
都归入L中
所有大于M的元素都归入到G中
而所有与之相等的元素
都归入到集合E中
此时的状态以及可能的情况
可以由这组图来表示
既然这三个集合之间
有明确的大小关系
所以无论如何
从大到小
它们必然是L在最左侧E居中
以及G在最右侧
当然它们的规模大小可能有所不同
不要忘了我们的查找目标
是在全局秩为K的那个元素
所以接下来我们可以沿用
quickselect算法的思路
根据不同的情况
相应的对问题的规模进行裁减
从而实现有效的减而治之
具体来说根据目标元素
具体应该落在L E或者G中
无非三种情况
如果L足够长
以至于K应该落在其中
那么不难看出E以及G都可以被减除掉
因此在这种情况下
我们接下来
只需将查找的范围缩减到子集L
然后递归的进行查找
对称的如果G足够大
则意味着E以及L都可以被减除掉
因此在这种情况下
我们同样可以将搜索的范围
缩小到子集G
并同样通过递归来完成后续的查找
需要注意的是
如果子集G是以序列形式给出的
那么在这个序列中
原先秩为K的那个目标元素
在G中所对应的秩将有所减少
在这里我们不要忘了对它及时的更新
那么最后一种情况
无非就是目标元素落在子集E中
不要忘了 E中的元素
都等于全局的那个中值
这意味着什么呢
没错
意味着全局的这个中值
恰好就是我们的查找对象
也就是说我们在这个位置已然命中
因此可以直接将其返回
这也是算法的最终出口
这个linearselect算法
尽管略显复杂
但是我们不难验证
它在功能上的正确性
因此我们接下来
需要回答的关键问题就是
它的时间复杂度有多高
是否如它的名字所暗示的那样
即便在最坏的情况下
也能保证不超过渐进的线性
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)概述
--07A-1 纵览
--07A-5 接口
-(a)概述--作业
-(b1)BST:查找
-第七章 二叉搜索树--(b1)BST:查找
-(b2)BST:插入
-(b2)BST:插入--作业
-(b3)BST:删除
-第七章 二叉搜索树--(b3)BST:删除
-(c)平衡与等价
-(c)平衡与等价--作业
-(d1)AVL树:重平衡
-第七章 二叉搜索树--(d1)AVL树:重平衡
-(d2)AVL树:插入
-(d2)AVL树:插入--作业
-(d3)AVL树:删除
-(d3)AVL树:删除--作业
-(d4)AVL树:(3+4)-重构
-(d4)AVL树:(3+4)-重构--作业
-本章测验
--章节测验
-(a1)伸展树:逐层伸展
--习题
-(a2)伸展树:双层伸展
--习题
-(a3)伸展树:算法实现
--习题
-(b1)B-树:动机
--习题
-(b2)B-树:结构
--习题
-(b3)B-树:查找
--习题
-(b4)B-树: 插入
--习题
-(b5)B-树: 删除
--习题
-(xa1)红黑树:动机
--习题
-(xa2)红黑树:结构
--习题
-(xa3)红黑树:插入
--习题
-(xa4)红黑树:删除
-本章测验
--习题
-(b)散列:原理
--09B-3 数组
--09B-4 原理
--09B-5 散列
--09B-6 冲突
--习题
-(c)散列:散列函数
--习题
-(d1)散列:排解冲突(1)
--习题
-(d2)散列:排解冲突(2)
--习题
-(e)桶/计数排序
--习题
-本章测验
--本章测试
-(a1)需求与动机
--习题
-(a2)基本实现
--习题
-(b1)完全二叉堆:结构
--习题
-(b2)完全二叉堆:插入与上滤
--习题
-(b3)完全二叉堆:删除与下滤
--习题
-(b4)完全二叉堆:批量建堆
--习题
-(c)堆排序
--习题
-(xa1)左式堆:结构
--习题
-(xa2)左式堆:合并
--习题
-(xa3)左式堆:插入与删除
-本章测验
--本章测试
-(a)ADT
--习题
-(b1)串匹配
--习题
-(b2)蛮力匹配
--习题
-(c1)KMP算法:从记忆力到预知力
--习题
-(c2)KMP算法:查询表
--习题
-(c3)KMP算法:理解next[]表
--习题
-(c4)KMP算法:构造next[]表
--习题
-(c5)KMP算法:分摊分析
--习题
-(c6)KMP算法:再改进
-(d1)BM_BC算法:以终为始
-(d2)BM_BC算法:坏字符
-(d3)BM_BC算法:构造bc[]
-(d4)BM_BC算法:性能分析
-(e1)BM_GS算法:好后缀
-(e2)BM_GS算法:构造gs表
-(e3)BM_GS算法:综合性能
-(f1)Karp-Rabin算法:串即是数
-(f2)Karp-Rabin算法:散列
-本章测验
--本章测试
-(a1)快速排序:算法A
-- 12a1-5: 实例
--习题
-(a2)快速排序:性能分析
--习题
-(a4)快速排序:变种
-(b1)选取:众数
-(b3)选取:通用算法
--习题
-(c1) 希尔排序:Shell序列
--习题
-(c2)希尔排序:逆序对
-本章测验
--本章测试