中值查找——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))
posted @ 2018-06-08 20:08  顾杰伟  阅读(245)  评论(0编辑  收藏  举报