#!/usr/bin/python
import random
def rselect(array,k):
l = []
r = []
j = random.randrange(0,k)
p = array[j]
for i in array :
if i < p :
l.append(i)
elif i > p :
r.append(i)
if len(l) == k-1 :
return p
elif len(l) > k-1 :
return rselect(l,k)
else :
return rselect(r,k-len(l)-1)
a = [1,2,3,4,5,6,7,8]
for i in range(1,8):
print rselect(a,i)
算法流程:每次随即找一个数,然后把其他的数按照比它小放左边,比它大放右边的方法,放进两个列表
然后分情况继续从左边或者右边递归。
算法复杂度分析:
1.我们把一个数据量为n的问题的数据量为3/4的子问题称之为一个层。
2.很容易知道。T(n) = T(3/4*n) + O(n) . 因为a < b**d (1<4/3) ,根据主定理,我们得到这个递归式的复杂度为O(n)
3.下面证明我们只需要O(1)的次数就可以把这个算法从第j层推到第j+1层。因为当随机数选在25%-75%之间的时候,子问题的上界为3/4*n。而随机数选在25%-75%的期望为2.所以期望为2次。
4.复杂度计算公式 T = E( sum(c * n * Xj * ((3/4) ** j)) ) j = 1 to ??? 因为E(Xj)=2,所以为O(n)