算法导论第九章中位数和顺序统计量(选择问题)腾讯云开发者社区

本章如果要归结成一个问题的话,可以归结为选择问题,比如要从一堆数中选择最大的数,或最小的数,或第几小/大的数等, 这样的问题看似很简单,似乎没有什么可研究的必要,因为我们已经知道了排序算法,运用排序+索引的方式不就轻松搞定了?但细想,排序所带来的时间复杂度是不是让这个问题无形之中变得糟糕。那算法研究不就是要尽可能避免一个问题高复杂度地解决,让那些不敢肯定有无最优解的问题变得不再怀疑,这也是算法研究者所追求的一种极致哲学。既然排序让这个问题解决的性能无法确定,那我们就抛开排序,独立研究问题本身,看有没有确定性的,且更优的解决之道,所以,这就是本章所探讨的问题。

一、中位数和顺序统计量

中位数:用非形式化的语言描述:中位数表示这样的一位数,它所属集合的“中点元素”。如果集合元素n为奇数,则中位数为(n+1)/2处;如果n为偶数,则中位数出现在n/2(下中位数)和n/2+1(上中位数)处,一般无特殊说明,我们都取下中位数。

顺序统计量:在一个n个元素组成的集合中,第i个顺序统计量是该集合中第i小的元素。

最大值:第1个顺序统计量。

最小值:第n个顺序统计量。

选择问题:给定一个包含n个元素的集合A和一个整数i,1<=i<=n,我们需要得到一个整数x,其中有i-1个元素小于它,即第i个顺序统计量。

前面说过,这个问题最直观的解法是通过排序+索引的方式,但排序算法有多种,且时间复杂度略高。我们需要更低时间复杂度来解决这个问题,要求线性时间,即O(n)。我们总结下算法导论上提出的方法,一步步展示如何O(n)来解决这个问题。

二、最大值、最小值

1、O(n)求最大值、最小值

2、3/2n次比较同时求最大最小值

按照锦标赛法,同时求最大最小值,需要2(n-1)次比较,但是换一种思路,我们没必要一个元素比较两次,而是两个元素比较一次,然后得出大小关系,在分别和最大、最小值比较,这样两个元素就只用比较3次,总共就是3/2n次。这里要分奇偶数看待,但不管奇偶,都需要3/2n次。比较次数减少了,时间也就降低了。代码如下:

3、最坏情况下,n-lgn-2次比较求第二小的元素(习题9.1-1)

本处要求的时间复杂度中含有lgn,我们自然想到这恰好是由n个元素组成的二叉树中的树的高度。有了这个提示之后,我们把思考点放在如何将n个元素的比较转化成一棵二叉树来求。通过前面的决策树,我们知道,决策树中的叶子节点,就是n个元素的排序组合,那么对应过来,我们可以得到n个元素恰好也可以成为二叉树的叶子节点,那么只需通过两两比较就可以得到,如下:

1)将n个元素两两分组,若为奇数,则单出一个;

2)比较每组元素得到最小值,将其作为该组两个元素的父亲节点;

3)对每组得到的父亲节点再采用1)的方式,直到最终剩余一个元素,即根节点。

这样,我们采用自底向上的方式构建了一棵二叉树,比如集合(2, 1, 4, 3, 5),我们得到这样一棵树:

接下来,就是找第二小的元素,根节点是第一小的元素,我们从根节点往下遍历,就可以找到第二小的元素,如上图:第一次找到5,第二次3,第三次2,到达叶子节点,也就找到第二小的元素。现在我们来分析下时间复杂度:

1)自底向上比较建树需要n-1次比较;

2)自顶向下寻找需要lgn-1次比较(树高);

一般选择问题看起来要比找最大、最小值要复杂得多,但令人惊奇的是,这两个问题的渐近运行时间却是相同的,都为O(n)。本节介绍的这个算法很强悍,期望的时间复杂度就能达到O(n),但最坏情况下的时间复杂度却为O(n^2)。该算法采用的是快速排序章节中的Partition过程来得到划分的中点,如果该中点恰好等于选择的点,则即为所求,否则再在左右两个区间中用同样的方法再次寻找,伪代码如下:

实现代码如下:

习题9.2-3要求实现一个非递归的版本,如下:

前面说过,Randomized_Select在最坏情况下,时间复杂度为O(n^2),这取决与划分的元素在集合中的位置。本节介绍的Select算法就能达到这样的要求,Select算法的思想是保证集合的划分是个好的划分,所以,需要对Partition做一点修改,具体的算法步骤如下:

如何保证是一个好的划分,该算法采用计算中位数的中位数的方法,首先将集合划分为5个元素一组的集合,不够5个元素的,单独做一个集合;然后采用插入排序找到5个元素的中位数,再从找到的中位数找到中位数,这样双重的中位数就能够保证这是一个较好的划分。但是为什么是5个元素一组,书中没特别说明,我想这是一个多次尝试的经验值,通过多个值测试时间复杂度之后,发现5是最好的。我们也可以具体分析一下:

如上图,至少有一半的组中有3个元素大于x,不算x所在组和元素不足5个的组,大于x的元素个数至少为:

进而可以得到其递归式为:

同理,我们可以分析当划分为7个元素一组时(习题9.3-1),递归式为:

THE END
0.《数据结构》学习系列——排序(下)二路合并选择排序 直接选择排序 伪代码 算法分析 锦标赛排序(树选择排序) 堆排序 伪代码 合并排序法 二路合并排序 两个有序文件合并成一个大的有序文件 总结 选择排序 思想 对待排序的文件进行n次选择,其中第i次选择第i小(大)的记录放在第i(n-i+1)个位置上 jvzquC41dnuh0lxfp0tfv8Pgpl{bp8ftvkimg8igvcomu86662=45A:
1.选择排序及改进算法4.2树型选择排序---锦标赛排序 基本思想 树型选择排序也称为锦标赛排序。其基本思想是:先把待排序的n个元素两两进行比较,取出较小者,若轮空则直接进入下一轮比较;然后在⎡n/2⎤个较小者中,采用同样的方法进行比较,再选出较小者;如此反复,直到选出关键字最小的元素为止。重复上述过程,直到所有元素全部jvzquC41dnuh0lxfp0tfv8segr{{j~fpi1gsvrhng1jfvjnnu1>56B=;2
2.计算机大赛算法,计算机经典算法——锦标赛排序算法本文探讨了如何通过二叉树结构模拟单淘汰锦标赛,如乒乓球和网球比赛,解释了如何通过比较和排序算法简化选冠过程。重点介绍了锦标赛排序法及其在工程中的应用,以及如何用最少比赛次数确定前3名。 关键词:二叉树 生活中的淘汰锦标赛:在单淘汰的锦标赛中,选手们两两比赛,胜者晋级,败者被淘汰。比如世界乒乓球锦标赛或者jvzquC41dnuh0lxfp0tfv8|gkzooa<832:7178ftvkimg8igvcomu863:9>43:;
3.数据结构选择排序树形选择排序堆排序树形选择排序①简单选择排序。 ②树形选择排序。←this ③堆排序。 树形选择排序(Tree Selection Sort),又称锦标赛排序(Tournament Sort)是一种按照锦标赛的思想进行选择排序的方法。 描述过程:首先对n个记录的关键字进行两两比较,然后在其中[n/2](取上界)个较大(小)者之间再进行两两比较,选出最大(小)关键字的记录为止。jvzquC41dnuh0lxfp0tfv8IqwDupoOq{1cxuklqg1fkucrqu196289628
4.10种排序算法精讲主要排序法有: 一、冒泡(Bubble)排序——相邻交换 二、选择排序——每次最小/大排在相应的位置 三、插入排序——将下一个插入已排好的序列中 四、壳(Shell)排序——缩小增量 五、归并排序 六、快速排序 七、堆排序 八、拓扑排序 九、锦标赛排序 jvzquC41dnuh0lxfp0tfv8ihcyksv;8671gsvrhng1jfvjnnu1713;82639
5.排序算法精讲在面试中经常会遇到排序算法的问题,尤其以快速排序、归并排序和堆排序。最近闲下来,把常用的排序算法做一个整理,对自己进行总结,以期对他人有点帮助。 各类算法总结 插入排序 最早拥有排序概念的机器出现在1901至1904年间由Hollerith发明出使用基数排序法的分类机,此机器包括打孔、制表等功能。 jvzquC41dnuh0lxfp0tfv8I222hfp9521cxuklqg1fkucrqu16?32B723
6.排序算法实现及复杂度分析(三)树形选择排序又称锦标赛排序,是一种按照锦标赛的思想进行选择排序的方法。首先对n个记录的关键字进行两两比较,然后在[n/2]个较小者之间进行两两比较,如此重复,直至选出最小关键字的记录为止。 它的时间复杂度为O(nlog2n),需要较多的辅助空间。 3.3、堆排序: jvzquC41dnuh0lxfp0tfv8lcxktop8ftvkimg8igvcomu8949889:
7.数据结构与算法代码整理:常见的选择排序法hanahimi1#选择排序法2defSelectSort(s):3n =len(s)4foriinrange(n-1):5min =i6forjinrange(i+1,n):7ifs[j]=2:#当存在两个以上的竞争者时,继续比赛(经过处理,nn必为偶数)14nnjvzquC41yy}/ewgnqiy/exr1jctbjrrk1r559;98394ivvq