http://hi.baidu.com/guoliqiang2006/blog/item/c019b700ed13a8dd277fb5ce.html
1.选择最大(或最小)元素。
时间复杂度为:O(n)
显然如果想要得到最大或最小元素要淘汰掉n-1个元素,所以最少需要n-1次比较,时间复杂度为O(n)
2.选择最大和最小元素。
如果先遍历一遍选择出最大元素,再遍历第二次找出最小元素,显然需要(n-1)+(n-2)=2n-3次比较。时间复杂度为O(n)
如果采用分治法:
1.将n个元素分成n/2组,每组两个数据。(如果n为奇数,分成(n/2+1)组,最后一组一个数据。下面的步骤
假设n为偶数)
2.每个组中两个数据比较,得到n/2较大元素,n/2个较小元素。此步骤比较n/2次。
3.遍历n/2个较大元素,找出最大的元素。此步骤比较n/2-1此。
4.遍历n/2个较小元素,找到最小元素。此步骤比较n/2-1此。
此方法一共比较(3/2)*n-2次。比较次数小于上面的方法,但时间复杂度的阶没变,依旧是O(n)
可以看到上面只使用了一步分支法,如果一直使用下去,就是把n分成2个n/2,再把一个n/2分成两个n/4,.......
可以证明其比较次数依旧是(3/2)*n-2次。
3.选择第二大元素。
可是使用上面的方法,其比较次数是(3/2)*n-2。我们采用锦标赛算法可以使比较次数降到
(n-1)+(log(n)-1)次但时间复杂度的阶依然是O(n)。
锦标赛算法:
1. k <-- n
2.k个数据两两分组,分成k/2组。
3,每组数据比较,淘汰较小者,但较小者要放在较大者淘汰数据链表中。这样剩下k/2个数据。
4,k <- k/2
5,如果k>1 goto 2
6.在最大元素的淘汰数据链表中遍历一遍,找链表中的最大的元素即为第二大元素。
找最大元素比较n-1次,找第二大元素比较log(n)-1次,一共比较(n-1)+(log(n)-1)次。
以下是选择第二小元素比较次数的解析(http://www.cnblogs.com/phishine/articles/1205351.html)
在算法导论中习题9-1提出,在最坏情况下利用 n + - 2 次比较,找出n个元素中第二小的元素。
其方法叫做 tournament method, 算法实现如下:
对数组a[1…n] 中元素成对的做比较,每次比较后讲较小的数拿出,形成的数组再继续这样处理,直到剩下最后的一个,就是数组中最小的那个。将这个过程以一个树的形式表现出来,如下图:
![](https://i-blog.csdnimg.cn/blog_migrate/aae1ab596419134e2e9b9d65e00f24d0.jpeg)
在这个过程中,非树叶节点就是比较的次数,一共进行了n-1 次比较,树根即为最小的元素。而第二小的元素一定是在这个过程中与根节点进行过比较的元素。即上图中5,3和2。这样的节点最多有个,在这些节点中找到最小的元素需要进行
-1次比较。因此总共所需的比较次数为 n-1 +
-1 = n+
-2 次
4.选择第k大元素。
这个问题参经分析过,当时只是简单的应用了快速排序的思想,(http://hi.baidu.com/guoliqiang2006/blog/item/254ba25950c238d69c8204be.html)这种方法如果不采用预处理的话是件复杂度一般都会在O(n log(n)),原因是参加分划的元素是总能将原来的数据分成比较均衡的两块。
其实选择第k大元素如果在采用分划思想的基础上加上一点预处理,就可以
将时间复杂度降低到O(n)。