【算法】--中值和顺序统计

在一个由$n$个元素组成的集合中,第$i$个顺序统计量(order statistic)是该集合中第$i$小的元素。一个中位数(median)是它所属集合的"中点元素”。如果不考虑$n$的奇偶性,中位数总是出现在$i=\lfloor(n+1) / 2\rfloor$处(下中位数)和$i=\lceil(n+2) / 2\rceil$处(上中位数)。
为了简便起见,本文的“中位数”都是指下中位数。本文将讨论从一个由n个互异的元素构成的集合中选择第i个顺序统计量的问题。
## 一、最大值与最小值
如何找到序列的最大值与最小值?最直观的方法就是遍历并记录当前最大值(或最小值),这种做法需要比较$n-1$次,但是如果想同时找到最大值和最小值,就要做$2n-2$次比较。
事实上,我们只需要最多$3*\lfloor n / 2\rfloor$次比较即可同时找出最大值与最小值。但我们并不是将每一个输入元素与当前的最小值和最大值进行比较—这样做的代价是每个元素需要2次比较,而是对输入元素成对地进行处理。首先,我们将对输入元素相互进行比较,然后把较小的与当前最小值比较,把较大的与当前最大值进行比较。这样每两个元素共需要三次比较。
## 二、期望为线性时间的选择算法
RANDOMIZED-SELECT算法是以快速排序算法为模型。与快速排序一样,我们仍然将输入数组进行递归划分。但与快速排序不同的是,快速排序会递归处理划分的两边,而RANDOMIZED-SELECT只处理划分的一边。这一差异会在性能分析中体现出来:快速排序的期望运行时间是
$\Theta(n \lg n)$,而 RANDOMIZED-SELECT的期望运行时间为$\Theta(n)$。
RANDOMIZED- SELECT利用了RANDOMIZED-PARTITION过程。与RANDOMIZED-QUICK SORT一样,因为它的部分行为是由随机数生成器的输出决定的,所以RANDOMIZED-SELECT也是一个随机算法。它返回数组$A[p,..,r]$中第$i$小的数.
```
RANDOMIZED- SELECT (A, p, r, i)
if p==r
    return A[p]
q=RANDOMIZED-PARTITION(A, P, r)
k=q-p+1
if i==k //the pivot value is the answe
    return A[q]
else if i<k
    return RANDOMIZED-SELECT(A, P,q-1, i)
else return RANDOMIZED- SELECT(A, q+, r, i-k)
```
为了分析RANOOMIZED-SELECT的期望运行时间,我们设该算法在一个含有n 个元素的输入数组$A[p.. r]$上的运行时间是一个随机变量,记为$T(n)$。
设$X_{k}=I{子数组A[p..q]正好包含k个元素}$,假设元素互异,则有$E[X_{k}]=1/n$。
对一个给定的RANOOMIZED­-SELECT, 指示器随机变量凡恰好在给定的K值上取值1, 对其他值都为0。当$X_{k}=l$ 时,可能要递归处理的两个子数组的大小分别为k-1 和n-k。因此可以得到递归式:
![](https://static.waverly.top/img/20200412112804.png#vwid=470&vhei=146)
两边取期望值,可得:
![](https://static.waverly.top/img/20200412112825.png#vwid=539&vhei=378)
因此:
$$\mathrm{E}[T(n)] \leqslant \frac{2}{n} \sum_{k=\lfloor{n/2}\rfloor}^{n-1} \mathrm{E}[T(k)]+O(n)$$
假设$\mathrm{E}[T(n)]=O(n)$,则有$\mathrm{E}[T(n)] \leqslant \mathrm{cn}$,通过归纳假设可得:
![](https://static.waverly.top/img/20200412113249.png#vwid=546&vhei=575)
故$\mathrm{E}[T(n)]=O(n)$可以得出结论:
**假设所有元素是互异的,在期望线性时间内,我们可以找到任一顺序统计量,特别是中位数。**
## 三、最坏情况为线性时间的选择算法
SELECT使用的也是来自快速排序的确定性划分算法 PARTITION,但做了修改,把划分的主元也作为输入参数。通过执行下列步骤,算法 SELECT可以确定一个有n>1个不同元素的输入数组中第i小的元素。(如果n=1,则 SELECT只返回它的唯一输入数值作为第i小的元素。)
1. 将输入数组的n个元素划分为$\lceil{n/5}\rceil$组,每组5个元素,且至多只有一组由剩下的${n}\mod {5}$个元素组成。
2. 寻找这$\lceil{n/5}\rceil$组中每一组的中位数:首先对每组元素进行插入排序,然后确定每组有序元素的中位数。
3. 对第2步中找出的$\lceil{n/5}\rceil$个中位数,递归调用 SELECT以找出其中位数$x$(如果有偶数个中位数,为了方便,约定$x$是较小的中位数)。
4. 利用修改过的 PARTITION版本,按中位数的中位数x对输入数组进行划分。让$k$比划
分的低区中的元素数目多1,因此$x$是第$k$小的元素,并且有$nk$个元素在划分的高区。
5. 如果i=k,则返回x。如果$i<k$,则在低区递归调用 SELECT来找出第i小的元素。如果
$i>k$,则在高区递归查找第$i-k$小的元素。
![](https://static.waverly.top/img/20200412105449.png#vwid=353&vhei=487)
通过递归式:
![](https://static.waverly.top/img/20200412113312.png#vwid=585&vhei=79)
可得:$T(n)=O(n)$

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值