![409972a9d550524dc934cde06fd3d3f0.png](https://i-blog.csdnimg.cn/blog_migrate/e37c5884da932556e9b5de8b42fdefc7.png)
前言
上一讲基于对策论分析了极端值的选择问题,明确了对策论的基本思路,也讨论了找极大元、极小元的时间复杂度下界。这一讲将讨论次大元的选择问题。
一、次大元选择策略
想找到次大元,我们肯定要知道最大元是什么,基于这个思路提出三种策略。
- 冒泡法
第一趟冒泡法找到最大元,第二趟冒泡法寻找最大元之外的剩余元素的最大值。
这样时间复杂度为2n-3。
缺点:这种策略问题在于第二趟没有利用到第一趟的排序信息,导致两趟排序各自单干的现象。
我们分析出一个信息是:任何败给除最大值之外的其他数据元素的都不可能成为次大元。
基于这个思想,提出第二种策略。
2. 胜利者法
思路:我们观察到,次大元是仅仅输给了最大元的元素,因此我们在直接与最大元比较的元素中采用冒泡法寻找次大元。
考虑一种情况
,比较 | 胜利者 |
---|---|
x1,x2 | x1 |
x1,x3 | x1 |
x1,x4 | x4 |
x4,x5 | x4 |
max=x4,直接与x4比较的有x1,x5,那么次大元会在这两个元素中产生,只需要使用冒牌法比较一次即可,总比较次数5次。
我们进而来分析最坏情况。
比较 | 胜者 |
---|---|
x1,x2 | x1 |
x1,x3 | x1 |
x1,x4 | x1 |
x1,x5 | x1 |
max=x1,直接与x1比较的有x2,x3,x4,x5,那么第二趟冒泡还要比较3次,一共比较7次,2n-3次,相比第一种策略没有进步。因此这种策略最坏情况没有什么改善,仍然存在一定的缺点。因此提出了锦标赛法。
3. 锦标赛法
思路:仍旧是在直接与最大元比较的元素中采用冒泡排序找最大值。
步骤:①找最大元采用锦标赛的方法,同时找到与最大元直接比较过的元素。
②使用冒泡排序找次大元。
多轮制锦标赛法:
每轮中元素成对比较,胜者进入下一轮,若奇数元素个数,则轮空者直接进入下一轮。直到最后一轮找到最大者结束。
过程及时间复杂度分析:
(1)锦标赛法建完全二叉树求最大值同时得到与最大值直接比较过的的元素——
(2)冒泡法在直接败给max的元素中找次大值——
![9e750449862d558baec97a05d69e906e.png](https://i-blog.csdnimg.cn/blog_migrate/44bd560f5f0d087ed22835be1979ffdd.jpeg)
n-1次比较之后得到最大元78,此时树高
算法实现:
算法使用数组来实现。
![e6f9d9bd918ab165ea936e5e3b478403.png](https://i-blog.csdnimg.cn/blog_migrate/39aacafb3a0d135dfbdd9557f40aeb79.jpeg)
![545312238310bb034a18d1cd0d1bbd63.png](https://i-blog.csdnimg.cn/blog_migrate/7e71d20c4826ac2ff6743c404032c99a.jpeg)
![fc9dadc600568338dc2cb7fd7048d062.png](https://i-blog.csdnimg.cn/blog_migrate/157be8bff53d16f0a6d5bbd28ac0e801.jpeg)
![8381d2e6956abe4e592c2d3c951e61ca.png](https://i-blog.csdnimg.cn/blog_migrate/bdafc7a841880af2095251a80f716b85.jpeg)
![d956c4384aa5e2065acc2b2477a41ab9.png](https://i-blog.csdnimg.cn/blog_migrate/3867c929338064ed4a8364b7e2339bbc.jpeg)
![69ae743d36f926bf53d57c47baac7b1a.png](https://i-blog.csdnimg.cn/blog_migrate/507f0f355b69e23f5d029830c99716fa.jpeg)
![d21d6d7eb3e3d354cab72421c05ed264.png](https://i-blog.csdnimg.cn/blog_migrate/0ac2854873b8e3a3064a0dd577e42c72.jpeg)
![801d83db408126def157a4b738404b62.png](https://i-blog.csdnimg.cn/blog_migrate/fd50727567c9514a6da20618e00100eb.jpeg)
这里给出一个伪代码,来描述这个过程。
![cafac16a3bc1e9c5f333f1101b6539b2.png](https://i-blog.csdnimg.cn/blog_migrate/f75b7cbb2caa08e8d1759c6a5b457453.jpeg)
二、对策论分析
定理5.2
n个数据元素中找次大元最坏情况下至少需要比较
证明:
(1)找最大元才能找到次大元,因此找最大元需要n-1次比较才能完成。
(2)找次大元,我们构造一个对策论策略:
![27c74c7a1f02f95dc874b7f1920994bf.png](https://i-blog.csdnimg.cn/blog_migrate/9d654e2eff904c086372fff286e01572.jpeg)
我们很容易发现下面几条性质:
- 一个元素失败过,权重就会变为0
- 根据策略,只要某个元素权重为0,就会一直保持为0
- 这个输入策略中所有元素的权值总和不变为n
为什么这么构造是最坏情况呢?
参考策略2,胜者法的最坏情况,我们让赢者恒赢,这样一旦输给了最大值,则需要冒泡法找次大元的时间复杂度就会是最大的。
比如,有下面这样一个构造。
![ed32ee581902f4aa28e7e71bf5e74268.png](https://i-blog.csdnimg.cn/blog_migrate/d490612f40e989863a353d4c25ac5b36.jpeg)
分析时间复杂度:
基于上面的对策策略,若x,y比较只会出现两种情况,一种是两个元素权值相同,我们不失一般性让x赢,则更新后的x的权重为2w(x),第二种情况是x,y其中一者较大,则我们让大者恒大,则更新后的权值为new<2w(x)(或new<2w(y))。我们假设x都比y大,则有下面的公式推导
![89e18d6da6c480af8dc9545f839c6271.png](https://i-blog.csdnimg.cn/blog_migrate/564bc961436e5cb0d4b7480d1159de46.png)
红色划线处删掉。
假设一共比较了k次,则
那么max最坏情况下至少参加了
那么将(1)(2)过程加和得到时间复杂度为
总结
这里提出了锦标赛的方法来解决次大元的选择问题,并使用对策论证明了这种方法的优越性,是最优算法。
下一讲将介绍中间元的选择策略。