线性时间选择算法

给定线性序集a[p..r]中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素

template<class Type>
Type RandomizedSelect(Type a[],int p,int r,int k)
{
  if (p==r) return a[p];
  int i=Randomizedpartition(a,p,r),
  j=i-p+1;
  if (k<=j) return RandomizedSelect(a,p,i,k);
  else return RandomizedSelect(a,i+1,r,k-j);
}
1 template<class Type>
2 Type RandomizedSelect(Type a[],int p,int r,int k)
3 {
4 if (p==r) return a[p];
5 int i=Randomizedpartition(a,p,r),
6 j=i-p+1;
7 if (k<=j) return RandomizedSelect(a,p,i,k);
8 else return RandomizedSelect(a,i+1,r,k-j);
9 }

-线性时间选择算法
-给定线性序集a[p..r]中n个元素和一个整数k,1≤k≤n,要求找
出这n个元素中第k小的元素
• 在最坏情况下,算法RandomizedSelect需要Ω(n2
)计算时间
• 但可以证明,算法RandomizedSelect可以在O(n)平均时间内
找出n个输入元素中的第k小元素。


实例:选第k小元素例:取阈值为6,设数组A有28个元素如下,

A[1…28]={8,33,17,51,57,49,35,11,25,37,14,3,2,13,52,12,6,29,3
2,54,5,16,22,23,7,61,36,9},求A中值元素,即第14小元素。
(k=14)

1.∵28>6,∴不能直接找,进入(2);

2.按5个一组分组(8,33,17,51,57);(49,35,11,25,37);(14,3,2,13,52);(12,6,29,32,54);(5,16,22,23,7)

3.每组按升序排序:(8,17,33,51,57);(11,25,35,37,49);(2,3,13,14,52);(6,12,29,32,54);(5,7,16,22,23)。

4.中值的集合M={33,35,13,29,16}。

5.递归找到中值的中值m=29。

6.把A分为三组:

  • A1= {8,17,11,25,14,3,2,13,12,6,5,16,22,23,7,9};
  • A2={29};
  • A3={33,51,57,49,35,37,52,32,54,61,36}。

因为k=14<|A1|=16,丢掉A2和A3,而第14小元素必然在A1中。

7.对集合A=A1重复上述过程

8.对集合A=A1按5个一组分组:(8,17,11,25,14);(3,2,13,12,6);(5,16,22,23,7)。

9.每组排序:(8,11,14,17,25);(2,3,6,12,13);(5,7,16,22,23)

10.找到新的中值集合M={14,6,16}

11.中值的中值m=14。

12.把A分为三组:
A1={8,11,3,2,13,12,6,5,7,9};A2={14};A3={17,25,16,22,23}

因为k=14>|A1|+|A2|=11,丢掉A1和A2,而第14小元素必然在A3中

13.设A=A3={17,25,16,22,23}然后在A3中找第k(=14-11=3)小元素。

14.A3={17,25,16,22,23},由于|A3|<6,所以直接找到第3小元素为22。

posted @ 2020-02-19 23:42  cenvent  阅读(815)  评论(0)    收藏  举报