元素选择又称顺序统计学,无非包含在一个数据集中查找最小的数,最大的数,中位数,第K位数,前K小数。。。云云。
1. 查找最小数,查找最大数:
顺序查找,比较次数 n—1 ,复杂度为O(n)
如果同时查找出最大最小数,则采取如下方法 FindMinMax(A)
FindMinMax(A):
1. 将n个元素两两分为 n/2 组
2. 每组进行比较,则会得到 n/2 个较小和 n/2 个较大的数据集合
3. 在 n/2 个较小数据集合中查找最小min
4. 在 n/2 个较大数据集合中查找最大max
5. 如果是基数,则为 n/2 +1
复杂度分析:
2. 比较 n/2 次
3.4 比较 (n/2 - 1) + (n/2 - 1) = 2 * (n/2) - 2 次
最终得 3 * n/2 - 2 次
(在分组的时候减少了 n/2 次比较,个人认为也就优化在此)
2. 一般性选择问题:
中位数的定义为位置处在中间的数,当i奇数时为 (i+1)/2,偶数时为两个 i/2 和 (i+1)/2
(王晓东一本书中提到select方法,后续文章将对此方法进行讨论)
本文采用一种类似快速排序的思想(随机化算法)来解决此问题
random-select (A, p, r, i)
if p = r
then return A[p]
q <- random-partition(A, p, r) //在A数组中,随机选取一个主元,位置为q,并将其划分
k <- q - p + 1;
if i = k
then return A[q];
elseif i < k
then return random-select (A, p, q - 1, i)
else
return random-select (A, q + 1, r, i - k)
复杂度: 平均复杂度为O(n), 最坏情况为O(n^2)
3. 选取第二大的元素:
算法1: 顺序比较找到最大max并将其删除,再从剩下的 n - 1个数中找最大。
复杂度: n - 1 + n - 2 = 2n - 3
算法2: 锦标赛算法 (后续博文讨论)
复杂度为 n + log n - 2
4. 选取前k小元素:
算法1: 运用select方法或者random-select算法选取到第k个位置的数
顺序查找
复杂度为: O(n) + n - 1 = O(n)
算法2: 将元素建最小堆,再取K次元素
复杂度为 O(n * log n)