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 + 1N 的元素. 当该元素小于堆顶元素的时候,将该元素插入到堆中,将堆顶元素出堆. 遍历(输入)结束后, 堆顶元素即为我们要找的元素.

相应的选择第 k 大的元素时, 我们考虑用一个 k 大小的小顶堆.对数组从头开始遍历. 头 k 个元素用于建立 k 大小的小顶堆. 对于从 k + 1N 的元素. 当该元素大于堆顶元素的时候,将该元素插入到堆中,将堆顶元素出堆. 遍历(输入)结束后, 堆顶元素即为我们要找的元素.

这样可得这个算法的时间复杂度为 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 选择算法 - 编程珠玑(续) 笔记的更多相关文章

  1. 算法线性编程珠玑读书笔记之----->使用线性算法求解连续子序列的最大和

    这段时间笔者几篇文章介绍了改算法线性的文章. 关联文章的地址 这个算法我在我的博客里应用动态规划做过,详细实现请参阅我的dp板块,下面给出书上最快的算法,时间复杂度为O(n),称之为线性算法. #in ...

  2. 学习笔记之编程珠玑 Programming Pearls

    Programming Pearls (2nd Edition): Jon Bentley: 0785342657883: Amazon.com: Books https://www.amazon.c ...

  3. 《编程珠玑,字字珠玑》读书笔记完结篇——AVL树

    写在最前面的 手贱翻开了<珠玑>的最后几章,所以这一篇更多是关于13.14.15章的内容.这篇文章的主要内容是“AVL树”,即平衡树,比红黑树低一个等次.捣乱真惹不起红黑树,情况很复杂:而 ...

  4. 读书笔记--编程珠玑II

    学化学的应该都知道chemdraw,这是一款专门绘制化学结构的软件,什么苯环.双键各种word难以搞定的分子式,你可以轻松的用chemdraw完成,可以称得上化学工作者居家旅行必备的良药.其实早在19 ...

  5. 编程珠玑I算法总结

    主要是根据编程珠玑后面的Algorithm附录总结了一下这本书里面的经典算法. 1 辗转相减求最大公约数 思想:最大公约数能整除i和j,则其一定也能整除i-j(if i>j) int gcd(i ...

  6. 一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS.

    一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS. 选择算法也就是求一个无序数组中第K大( ...

  7. python核心编程第二版笔记

    python核心编程第二版笔记由网友提供:open168 python核心编程--笔记(很详细,建议收藏) 解释器options:1.1 –d   提供调试输出1.2 –O   生成优化的字节码(生成 ...

  8. 《[MySQL技术内幕:SQL编程》读书笔记

    <[MySQL技术内幕:SQL编程>读书笔记 2019年3月31日23:12:11 严禁转载!!! <MySQL技术内幕:SQL编程>这本书是我比较喜欢的一位国内作者姜承尧, ...

  9. 《C#高级编程》读书笔记

    <C#高级编程>读书笔记 C#类型的取值范围 名称 CTS类型 说明 范围 sbyte System.SByte 8位有符号的整数 -128~127(−27−27~27−127−1) sh ...

随机推荐

  1. mysql 定时每秒插入一条数据

    1.创建表 2.创建存储过程 CREATE PROCEDURE user()INSERT INTO user(name,sex) VALUES ('1111','1'); 3.创建定时器 CREATE ...

  2. [Java] 使用 Apache的 Commons-net库 实现FTP操作

    因为最近工作中需要用到FTP操作,而手上又没有现成的FTP代码.就去网上找了一下,发现大家都使用Apache的 Commons-net库中的FTPClient. 但是,感觉用起来不太方便.又在网上找到 ...

  3. GenIcam标准(一)

    1.概述 如今的数码摄相机包含了很多的功能,而不仅仅是采集图像.对于机器视觉相机来说,处理图像并把结果附加到图像数据流上,控制附加的硬件,代替应用程序作实时的处理等都是很平常的事情.这也导致了相机的编 ...

  4. Visual Assist X 10.8.2036的Crack破解补丁.2014.05.22 (General release.)

    说起来,VA公布上一个Genreal Release版本号已经是过春节那阵子时候的事了,时间过得真快. VA小组又给我们带来了新版本号的Visual Assist编码助手的 2036 版本号, 这个版 ...

  5. 【大话QT之十六】使用ctkPluginFramework插件系统构建项目实战

    "使用ctkPluginFramework插件系统构建项目实战",这篇文章是写博客以来最纠结的一篇文章. 倒不是由于技术都多么困难,而是想去描写叙述一个项目架构採用ctkPlugi ...

  6. Android 中如何使用 enum / 枚举

    如何在Android开发中合理的使用enum 欢迎大家访问我的Github开源库,这里有好玩的App源码,想和大家分享.https://github.com/ChoicesWang 转载请注明:htt ...

  7. Fast Flux技术——本质就是跳板,控制多个机器,同一域名指向极多的IP(TTL修改为0),以逃避追踪

    转自:http://ytuwlg.iteye.com/blog/355718 通过病毒邮件和欺诈网站学到的对付网络封锁的好东西:Fast Flux技术 收到一封邮件,引起我的好奇了: 邮件标题是:Ha ...

  8. kibana 5.5 源码编译踩坑记录

    由于项目需要定制开发kibana,因此需要编译kibana,在开发环境下运行.   注意:必须下载kibana 5.5的源码才能正常编译,下载release或者snapshot版本是不行的,运行npm ...

  9. Lists are mutable

    The syntax for accessing the elements of a list is the same as for accessing the characters of a str ...

  10. 外部样式表声明的样式并不会进入style对象

    在网页设计当中,我们注重网页的行为(js).结构(HTLM).样式(css)分离开 内联样式表或者内部样式表声明的样式信息都会进入style对象. 我们可以测试一下: 但是我们的外部样式表,也就是通过 ...