Select 选择算法 - 编程珠玑(续) 笔记
Select 算法
I 编程珠玑(续)介绍的 Quickselect 算法
选择 N 个元素中的第 K 小(大)值,是日常场景中常见的问题,也是经典的算法问题.
选取 N 个元素的数组的中的第 K 小(大)值,最简单的想法是将数组排序后直接选取. 那么这种方法的时间复杂度是O(N log N).
C.A.R.Hoare 提出的 Quickelect 算法的平均时间复杂度达到了 O(N) . 在去递归之后, 是原地算法. 这个算法因为其简洁,高效而被广泛使用.
算法思路的C++实现如下.
int select(vector<int>& X, int k) {
int l = 0, u = X.size() - 1;
while(l < u){
swap(X[l], X[rand()%(u-l+1)+l]);
int m = l;
for(int i = l + 1; i <= u; i++)
if(X[i] < X[l])
swap(X[++m], X[i]); //m在i遍历的过程中,是遍历过的元素中, 小于X[l]的元素的最大下标
swap(X[l], X[m]);
if(k <= m) u = m - 1;
if(k >= m) l = m + 1;
}
return X[k];
}
- 当 k 选定为数组的中位数时,平均所耗的时间最多.
- 当数组中有大量重复元素,或者是逆序排序的数组时,会增加运行时间. 遇到大量重复的元素时不能很快地缩小 l - u 的范围. 逆序数组会产生很多的 swap 操作.
- Worst-case peformance O(N ^ 2)
II 序列输入时使用的 Heap-Select 算法
考虑一个输入序列,要求在序列输入完毕的时候得出这个序列的第 k 大(小)的元素.
要选择第 k 小的元素时, 我们考虑用一个 k 大小的大顶堆. 对数组从头开始遍历(等价于数组线性输入), 头 k 个元素用于建立 k 大小的大顶堆. 对于从 k + 1 到 N 的元素. 当该元素小于堆顶元素的时候,将该元素插入到堆中,将堆顶元素出堆. 遍历(输入)结束后, 堆顶元素即为我们要找的元素.
相应的选择第 k 大的元素时, 我们考虑用一个 k 大小的小顶堆.对数组从头开始遍历. 头 k 个元素用于建立 k 大小的小顶堆. 对于从 k + 1 到 N 的元素. 当该元素大于堆顶元素的时候,将该元素插入到堆中,将堆顶元素出堆. 遍历(输入)结束后, 堆顶元素即为我们要找的元素.
这样可得这个算法的时间复杂度为 O(k) + O(N * log k) ==> O(N * log k)
由于要调用空间构造堆,空间复杂度为 O(k)
关于这个算法的正确性,用归纳法, 从已经输入k的数组中挑选头k个最大(小)的元素。 然后继续下去即可。
III 三个元素的中间值
杀鸡不用牛刀,三个元素的中间值用简单的三次比较就可以搞定.
if(X[1] > X[2])
swap(X[1], X[2]);
if(X[2] > X[3])
swap(X[2], X[3]);
if(X[1] > X[2])
swap(X[1], X[2]); //自此 X[1], X[2], X[3] 从小到大有序.
IV 其他的Select算法
Median of medians 又名 BFPRT算法. 基于Blum, Floyd, Pratt, Rivest and Tarjan 1973年的论文 Time Bounds for Selection. 拥有O(N) 的 worst case performance.
Introselect 则是BFPRT算法和 Quickselect 算法的结合. 默认使用 Quickselect ,在 Quickselect 表现出比较差的运行情况时转向Median of medians. 从而也能提供O(N) 的 worst case performance.
Select 选择算法 - 编程珠玑(续) 笔记的更多相关文章
- 算法线性编程珠玑读书笔记之----->使用线性算法求解连续子序列的最大和
这段时间笔者几篇文章介绍了改算法线性的文章. 关联文章的地址 这个算法我在我的博客里应用动态规划做过,详细实现请参阅我的dp板块,下面给出书上最快的算法,时间复杂度为O(n),称之为线性算法. #in ...
- 学习笔记之编程珠玑 Programming Pearls
Programming Pearls (2nd Edition): Jon Bentley: 0785342657883: Amazon.com: Books https://www.amazon.c ...
- 《编程珠玑,字字珠玑》读书笔记完结篇——AVL树
写在最前面的 手贱翻开了<珠玑>的最后几章,所以这一篇更多是关于13.14.15章的内容.这篇文章的主要内容是“AVL树”,即平衡树,比红黑树低一个等次.捣乱真惹不起红黑树,情况很复杂:而 ...
- 读书笔记--编程珠玑II
学化学的应该都知道chemdraw,这是一款专门绘制化学结构的软件,什么苯环.双键各种word难以搞定的分子式,你可以轻松的用chemdraw完成,可以称得上化学工作者居家旅行必备的良药.其实早在19 ...
- 编程珠玑I算法总结
主要是根据编程珠玑后面的Algorithm附录总结了一下这本书里面的经典算法. 1 辗转相减求最大公约数 思想:最大公约数能整除i和j,则其一定也能整除i-j(if i>j) int gcd(i ...
- 一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS.
一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS. 选择算法也就是求一个无序数组中第K大( ...
- python核心编程第二版笔记
python核心编程第二版笔记由网友提供:open168 python核心编程--笔记(很详细,建议收藏) 解释器options:1.1 –d 提供调试输出1.2 –O 生成优化的字节码(生成 ...
- 《[MySQL技术内幕:SQL编程》读书笔记
<[MySQL技术内幕:SQL编程>读书笔记 2019年3月31日23:12:11 严禁转载!!! <MySQL技术内幕:SQL编程>这本书是我比较喜欢的一位国内作者姜承尧, ...
- 《C#高级编程》读书笔记
<C#高级编程>读书笔记 C#类型的取值范围 名称 CTS类型 说明 范围 sbyte System.SByte 8位有符号的整数 -128~127(−27−27~27−127−1) sh ...
随机推荐
- mysql 基础函数语句
1:查看当前登陆用户 select user(): 2:切换数据库 use mysql; 查看该表用户 select user,host from user; 4:退出数据库 5:查看数据库版本 se ...
- [vue插件]基于vue2.x的电商图片放大镜插件
最近在撸一个电商网站,有一个需求是要像淘宝商品详情页那样,鼠标放在主图上,显示图片放大镜效果,找了一下貌似没有什么合适的vue插件,于是自己撸了一个,分享一下.小白第一次分享,各位大神莫见笑. vue ...
- java 实现顺序结构线性列表
package com.ncu.list; /** * * 顺序结构线性列表 * * @author liuhao * */ public class SquenceList<T> { p ...
- 【BZOJ 1218】 [HNOI2003]激光炸弹
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 一开始以为可以炸多次. 然后发现是一次. 那么久直接做个前缀和就好了 枚举正方形的左上角. 然后刚好和网格对齐的话. 肯定没有放在( ...
- ZOJ 2702 Unrhymable Rhymes
Unrhymable Rhymes Time Limit:10000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu De ...
- 【转】C#添加修改删除文件文件夹大全
[转]C#添加修改删除文件文件夹大全 C#添加修改删除文件文件夹大全 StreamWriter sw = File.AppendText(Server.MapPath(".")+& ...
- 洛谷 P3914 染色计数
P3914 染色计数 题目描述 有一颗NN个节点的树,节点用1,2,\cdots,N1,2,⋯,N编号.你要给它染色,使得相邻节点的颜色不同.有MM种颜色,用1,2,\cdots,M1,2,⋯,M编号 ...
- 洛谷 P3924 康娜的线段树
P3924 康娜的线段树 题目描述 小林是个程序媛,不可避免地康娜对这种人类的“魔法”产生了浓厚的兴趣,于是小林开始教她OI. 今天康娜学习了一种叫做线段树的神奇魔法,这种魔法可以维护一段区间的信息, ...
- Java的TreeMap,C++的lower_bound,合并间隔
https://leetcode.com/problems/data-stream-as-disjoint-intervals/?tab=Description 这道题目是合并间隔的经典题目. htt ...
- [Swift]forEach详解
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...