Python-函数递归-二分法

l=[1,2,10,30,33,99,101,200,301,402]  #从小到大排列的数字列表

num=200
for item in l:
    if num == item:
        print('find it')
        break

此寻找数字的方法,效率低;并且如果查找402,那么最后break就没有什么意思了。

下面用二分法:(一)

l=[1,2,10,30,33,99,101,200,301,402] #从小到大排列的数字列表
def get(num,l):
        mid=len(l)//2
        if num > l[mid]:
            #in the right
            l=l[mid+1:]
        elif num < l[mid]:
            #in the left
            l=l[:mid]
        else:
            print('find it')
            return
        get(num,l)

get(200,l)

def get(num,l):
        mid=len(l)//2
        if num > l[mid]:
            #in the right
            l=l[mid+1:]
            get(num, l)
        elif num < l[mid]:
            #in the left
            l=l[:mid]
            get(num, l)
        else:
            print('find it')
            return

get(200,l)

得来!

下面开始优化,得到寻找次数,和当前的中间值(二)

l=[1,2,10,30,33,99,101,200,301,402] #从小到大排列的数字列表
def get(num,l):
        mid=len(l)//2
        print(l,l[mid])
        if num > l[mid]:
            #in the right
            l=l[mid+1:]
        elif num < l[mid]:
            #in the left
            l=l[:mid]
        else:
            print('find it')
            return
        get(num,l)

get(200,l)

问题来了,如果想要取的值不存在呢?      get(3,l)

IndexError: list index out of range
[1, 2, 10, 30, 33, 99, 101, 200, 301, 402]
[1, 2, 10, 30, 33]
[1, 2]
[]

数值不存在的情况下,列表切空了也找不到这个值。

解决方法如下:

l=[1,2,10,30,33,99,101,200,301,402] #从小到大排列的数字列表
def get(num,l):
    print(l)
    if len(l) > 0: #列表不为空,则证明还有值是可以执行二分法逻辑的
        mid=len(l)//2
        if num > l[mid]:
            #in the right
            l=l[mid+1:]
        elif num < l[mid]:
            #in the left
            l=l[:mid]
        else:
            print('find it')
            return
        get(num,l)
    else: #列表为空,则证明根本不存在要查找的值
        print('not exists')
        return
get(403,l)

找到值的索引,代码如下:

 1 l=[1,2,10,30,33,99,101,200,301,402]
 2 
 3 def search(num,l,start=0,stop=len(l)-1):
 4     if start <= stop:
 5         mid=start+(stop-start)//2
 6         print('start:[%s] stop:[%s] mid:[%s] mid_val:[%s]' %(start,stop,mid,l[mid]))
 7         if num > l[mid]:
 8             start=mid+1
 9         elif num < l[mid]:
10             stop=mid-1
11         else:
12             print('find it',mid)
13             return
14         search(num,l,start,stop)
15     else: #如果start > stop则意味着列表实际上已经全部切完,即切为空
16         print('not exists')
17         return
18 
19 search(301,l)
列出查找值的索引

 

posted @ 2017-10-17 23:05  大雄猫  阅读(277)  评论(0编辑  收藏  举报