• 035 用Python实现的二分查找算法(基于递归函数)


    一、递归的定义

    1.什么是递归:在一个函数里在调用这个函数本身

    2.最大递归层数做了一个限制:997,但是也可以自己限制

    1 def  foo():
    2     print(n)
    3     n+=1
    4     foo(n)
    5 foo(1)
    验证997

    3.最大层数限制是python默认的,可以做修改,但是不建议你修改。(因为如果用997层递归都没有解决的问题要么是不适合使用递归来解决问题,要么就是你的代码太烂了)

    1 import sys
    2 sys.setrecursionlimit(10000000)#修改递归层数
    3 n=0
    4 def f():
    5     global n
    6     n+=1
    7     print(n)
    8     f()
    9 f()
    View Code

    我们可以通过以上代码,导入sys模块的方式来修改递归的最大深度。

    sys模块:所有和python相关的设置和方法

    4.结束递归的标志:return

    5.递归解决的问题就是通过参数,来控制每一次调用缩小计算的规模

    6.使用场景:数据的规模在减少,但是解决问题的思路没有改变

    7.很多排序算法会用到递归

    二、递归小应用

    1.下面我们来猜一下小明的年龄

    小明是新来的同学,丽丽问他多少岁了。

    他说:我不告诉你,但是我比滔滔大两岁。

    滔滔说:我也不告诉你,我比晓晓大两岁

    晓晓说:我也不告诉你,我比小星大两岁

    小星也没有告诉他说:我比小华大两岁

    最后小华说,我告诉你,我今年18岁了

    这个怎么办呢?当然,有人会说,这个很简单啊,知道小华的,就会知道小星的,知道小星的就会知道晓晓的,以此类推,就会知道小明的年龄啦。这个过程已经非常接近递归的思想了。

    小华 18+2
    小星 20+2
    晓晓   22+2
    滔滔   24+2
    小明  26+2

    上面的图我们可以用个序号来表示吧

    age(5) = age(4)+2
    age(4) = age(3) + 2 
    age(3) = age(2) + 2
    age(2) = age(1) + 2
    age(1) = 18

    那么代码该怎么写呢?

    1 def age(n):
    2     if n == 1:
    3         return 18
    4     else:
    5         return age(n - 1) + 2
    6 
    7 ret=age(6)
    8 print(ret)
    View Code

    2.一个数,除2直到不能整除2

    1 def  cal(num):
    2         if  num%2==0:#先判断能不能整除
    3             num=num//2
    4             return cal(num)
    5         else:
    6             return num
    7 print(cal(8))
    一个数,除2直到不能整除2

    3.如果一个数可以整除2,就整除,不能整除就*3+1

     1 def func(num):
     2     print(num)
     3     if num==1:
     4         return
     5     if num%2==0:
     6         num=num//2
     7     else:
     8         num=num*3+1
     9     func(num)
    10 func(5)
    如果一个数可以整除2,就整除,不能整除就*3+1

    三、三级菜单

    menu = {
    '北京': {
    '海淀': {
    '五道口': {
    'soho': {},
    '网易': {},
    'google': {}
    },
    '中关村': {
    '爱奇艺': {},
    '汽车之家': {},
    'youku': {},
    },
    '上地': {
    '百度': {},
    },
    },
    '昌平': {
    '沙河': {
    '老男孩': {},
    '北航': {},
    },
    '天通苑': {},
    '回龙观': {},
    },
    '朝阳': {},
    '东城': {},
    },
    '上海': {
    '闵行': {
    "人民广场": {
    '炸鸡店': {}
    }
    },
    '闸北': {
    '火车战': {
    '携程': {}
    }
    },
    '浦东': {},
    },
    '山东': {},
    }
     1 def threeLM(menu):
     2     while True:
     3         for key in menu:#循环字典的key,打印出北京,上海,山东
     4             print(key)
     5         name=input('>>>:').strip()
     6         if name=='back' or name=='quit':#如果输入back,就返回上一层。如果输入quit就退出
     7             return name #返回的name的给了ret
     8         if name in menu:
     9             ret=threeLM(menu[name])
    10             if ret=='quit':return 'quit'#如果返回的是quit,就直接return quit 了,就退出了
    11 threeLM()
    12 # print(threeLM(menu))#print打印了就返回出quit了,threeLM()没有打印就直接退出了
    三级菜单

    四、二分查找算法 

    从这个列表中找到55的位置l = 【2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88】

     

    这就是二分查找,从上面的列表中可以观察到,这个列表是从小到大依次递增的有序列表。

    按照上面的图就可以实现查找了。

     1 l = [2, 3, 5, 10, 15, 16, 18, 22, 26, 30, 32, 35, 41, 42, 43, 55, 56, 66, 67, 69, 72, 76, 82, 83, 88]
     2 def find(l,aim):
     3     mid=len(l)//2#取中间值,//长度取整(取出来的是索引)
     4     if l[mid]>aim:#判断中间值和要找的那个值的大小关系
     5         new_l=l[:mid]#顾头不顾尾
     6         return find(new_l,aim)#递归算法中在每次函数调用的时候在前面加return
     7     elif l[mid]<aim:
     8         new_l=l[mid+1:]
     9         return find(new_l,aim)
    10     else:
    11         return l[mid]
    12 print(find(l,66))
    简单的二分法
     1 l = [2, 3, 5, 10, 15, 16, 18, 22, 26, 30, 32, 35, 41, 42, 43, 55, 56, 66, 67, 69, 72, 76, 82, 83, 88]
     2 def func(l, aim,start = 0,end = len(l)-1):
     3     mid = (start+end)//2#求中间的数
     4     if not l[start:end+1]:#如果你要找的数不在里面,就return'你查找的数字不在这个列表里面'
     5         return  '你查找的数字不在这个列表里面'
     6     elif aim > l[mid]:
     7         return func(l,aim,mid+1,end)
     8     elif aim < l[mid]:
     9         return func(l,aim,start,mid-1)
    10     elif aim == l[mid]:
    11         print("bingo")
    12         return mid
    13 
    14 index = func(l,55)
    15 print(index)
    16 # print(func(l,41))
    升级版二分法
  • 相关阅读:
    28完全背包+扩展欧几里得(包子凑数)
    HDU 3527 SPY
    POJ 3615 Cow Hurdles
    POJ 3620 Avoid The Lakes
    POJ 3036 Honeycomb Walk
    HDU 2352 Verdis Quo
    HDU 2368 Alfredo's Pizza Restaurant
    HDU 2700 Parity
    HDU 3763 CDs
    POJ 3279 Fliptile
  • 原文地址:https://www.cnblogs.com/abdm-989/p/14161716.html
Copyright © 2020-2023  润新知