目录
1.问题
选择问题:
设L是n个元素的集合,从L中选取第k小的元素,其中1<=k<=n。
这里第k小的元素是指,当L按从小到大排好序之后,排在第k个位置的元素。
利用特定分治策略选出第k小的元素。
2.解析
3.设计
void select(vector<int>s,int n,int k){
把s划分成最多5个一组,共n/5组(向上取整)
把每组的中位数放到集合m
找出中位数的中位数m* //用于把s划分成ABCD四部分
把AD中的每个元素与m*比较大小,小的构成s1,大的构成s2
s1=s1并C,s2=s2并B //m*不存入s1或s2,直接丢弃
if k==s1.size
输出m*
return
else if k<=s1.size
select(s1,s1.size,k)
else
select(s2,s2.size,k-s1.size-1)
}
4.分析
假设k是5的倍数,且n/5是奇数,即n/5=2r+1,于是
如果A和D的元素都小于m*,那么它们的元素都加入s1,且下一步算法又在这个大的子问题上进行递归调用,这对应了归约后子问题规模的上界,是算法复杂度的最坏情况
子问题规模为:
表明子问题规模不超过原问题规模的7/10
所以
其中,为查找m*的时间,总规模n中选出n/5个数来找中位数
tn是构造中位数集合,以及AD和m*进行比较的时间开销,t是某个常数