【算法导论】第六课 顺序统计,中值

这一节课讲到两个线性算法,一个是顺序统计算法(Order Statistics)还有一个是最坏情况线性时间顺序统计法(Worst-case linear-time order statistics)

这两个算法是要解决这样一个问题:对于一个数组A,我们需要求得第k小的一个数,rank(k)
如果k=1, 就是求最小值
如果k=n, 就是求最大值
如果k=[(n+1)/2] or [(n-1)/2] 那么就是求中值

1. 采用随机分治的思想计算顺序统计
计算在数组 A[p,q] 中第i小的一个数 // p,q是数列的序号
写出这个算法的伪代码:
Rand-Select(A,p,q,i)
if p=q then return A[p]
r <- Rand-Partition (A, p,q) //在A[p,q] 之间随机取一个值r
k <- r-p+1 //k是r到序列头的长度

if i=k return A[r]
if i then return Rand-Select (A,p,r-1,i)
else return Rand-Select(A,r+1,q,i-k)
这个随机分治的方法如下图:
【算法导论】第六课 顺序统计,中值_第1张图片


接下来来分析这个算法,
与随机排序的分析方法差不多在除了worstcase的情况下,这个算法的复杂度都是θ(n)
而如果每次分治都只排除了一个元素的话 T(n)=T(n-1)+θ(n)那么T(n)=θ(n^2)
现在我们需要求这个T(n)的期望值,可以看出,T(n)的值依赖于不同的分治方式,这个分治方式又依赖于随机的指示变量,因此,构造一个随即指示器:
Xk=1 分割成k和n-k-1两段
Xk=0 其他情况
推导过程见课件,与快速排序法的过程类似
最终通过代换法我们可以知道
E[T(n)]≤cn,因此这个算法是线性的。

现在再来考虑一下,如果最坏的情况下,这种随机选择主元的方法会导致θ(n^2)的复杂度,那么能不能有一个算法能保证选择的主元是一个好的主元呢?

2.最坏情况线性时间顺序统计法(Worst-case linear-time order statistics)
我们需要的是一个好主元,这个时候就可以考虑我们可以递归的来选取主元,而不用随机选择
这个算法包含以下四个步骤
1)对于一个长度为n的数组,我们把这些元素组成一个5*[n/5]的阵列,并找出每一列的中值,时间复杂度θ(n)
【算法导论】第六课 顺序统计,中值_第2张图片
2)求出这些中值的中值,定义为x,时间耗费n/5
3)以x为划分元素,k为x的序号,递归的调用:
if i=k return x (这里有一个疑问,返回的x并不一定是数组n的中值)
if i if i>k then 在剩下的3/4部分里迭代的寻找第i-k小的数

分析:
这个算法有趣的地方在于选取的这个分化元素x和每一组的中值,把整个阵列分成了四个部分,如下图,
【算法导论】第六课 顺序统计,中值_第3张图片
其中左上部分的值一定是小于等于x的,右下部分的值一定是大于等于x,
在递归的时候,无论i大于还是小于k我们都能将运算的规模减小3*n/5/2=3n/10
T(n)=T(7n/10)+T(n/5)+θ(n)
由代换法可知,这个递归式的主导因子是θ(n),因此T(n)=θ(n)是一个线性的算法
但是,这个算法其实在现实中并不是那么好,因为c会取到很大,不见得就不随机选择主元的顺序统计法好。另外这个算法返回的x不一定就是第i小的数,我认为在准确性上还有待讨论。

你可能感兴趣的:(算法导论)