第九章 中位数和顺序统计
1. 最大值和最小值
单独求最大值和最小值,很简单,在这里不多说
对于同时找到最大值、最小值,有多种思路:首先,是分别找到最大值和最小值,两次遍历(2n-2);或者每个数都进行两次比较.
可以跟据第二种想法稍作改进,将两个数同时与最大值、最小值比较,那么这两个数就不必分别与最大、小值比较,而首先进行一次比较,选出较大值与最大值比较,较小值与最小值比较,此时需要(3*[n/2])。对于初始最大值和最小值的选择,可以根据数组的长度决定,如果数组长度是奇数,则第一个数据为最大最小值;如果为偶数,可以先将前两组数据进行一次比较。
2. 随机选择
算法伪代码(Random-select(A,p,q,i))如下:
if(p == q) return A[p];
r = Random-partion(A,p,q);
k = r - p +1;
if(i == k) return A[r];
if(i < k) return Random-select(A,p,r-1,i);
else return Random-select(A,r+1,q,i-k);
正常情况下的运行时间是线性的,此处略去证明;而最坏的情况下运行时间为,此时每次随机分割后数组都被分成1,n-1两部分,即 T(n)=T(n−1)+ .但如果你不是那种运气极度背的同学,相信你不会遇到这种情况.
3. 选择算法
select(i,n):
1. 划分元素
将输入的元素划分为组,每组五个元素,且至多只有一组由剩下的n mod 5个元素组成
2. 寻找中位数
寻找这组中每一组中位数:首先对每组元素排序,然后选出中位数
3.寻找中位数的中位数
对第二步中的个中位数,递归调用select以找出其中位
4. partion
利用修改过的partion,按中位数的中位数x对输入数组进行划分,
k = partion(A,0,n-1,x);
5. 递归
if(i == k) return x;
if(i < k) return select(i,k);
else return select(i-k,n-k);
关于随机算法的运行时间,最坏情况下仍为线性时间,证明略.