中值查找——Python中Sherwood选择算法实现
Sherwood思想寻找元素:
引入:
一个确定性算法A,(所谓确定,就是你不管运行几次,你的运行过程都是一样的),我们假设你是去二分查找一个元素,并且恰好是最差情况,运行了logn次,那么不管以后多少次运行这个程序,次数都是logn次。但是如果我们将middle值设为left-right中的一个随机值,那么每运行一次,过程都可能会不一样,我们知道随机就意味着平均化,每种结果都有可能,那么极端情况就会被避免,那么你的运行过程是最差情况的概率就会减小,而向平均情况靠拢。
用途:
一个算法,存在最佳情况,和最差情况,还有平均性能,当最佳情况和最差情况相差很多,我们就可以用sherwood算法实现将算法的性能向平均对齐。这样以后,每次运行性能都在平均水平上,最差情况就被磨平了,对于其他情况意义不大。
实例演示:
用舍伍德算法求乱序数组中值:
import random
list1=[12,8,3,5,7,2,9] #[2,3,5,7,8,9,12]
list2=[3,7,2,6,5,9] #[2,3,5,6,7,9]
#实现列表中元素交换操作
def swap(list,a,b):
temp =list[a]
list[a]=list[b]
list[b]=temp
#pos是寻找第几小,left是左边界,right是右边界
def select(list,left,right,pos):
while True:
if left>=right:
return list[left]
#从left-right中随机选择一个作为比较的轴值
r = random.randint(left,right)
if left != r:
swap(list,left,r) #将轴值放在数组开头,好方便以后的交换操作
pivot=list[left]
i=left+1
j=right
while True:
while i<7 and list[i] < pivot : #从左往右找到不小于轴值的元素
i=i+1
while list[j] > pivot and j>=i:#从右往左找到不大于轴值的元素
j=j-1
if i>=j:
break
swap(list,i,j) #将找到的两个元素交换
#将轴值放回它应在的位置,此时左边都不大于它,右边都不小于它。
list[left]=list[j]
list[j]=pivot
#重新确定寻找区间,找到就返回
t=j-left+1
if t==pos:
return pivot
elif t>pos:
right=j-1
else:
pos=pos-t #这里注意当左边界收缩时,它的pos也要收缩
left=j+1
print(select(list1,0,len(list1)-1,4))