python之路----递归函数(二分查找法)

递归函数  (关键点在于找到明确的函数结束点)

递归调用:在调用一个函数的过程中,直接或间接的调用了该函数的本身   而且递归函数必须要有一个结束条件

无限的递归理论上是不允许的   最大允许997层  也可以通过sys模块进行修改  但是本质递归层数与取决于电脑自身硬件内存

def func():
       print('>>>func')
       func()

func
   无限递归   无限
无限递归
查看最大递归层数

#面向函数编程
 mport sys  #python限制在997/998
 ys.setrecursionlimit(10000000)  #可以修改
COUNT = 0
def func():  #recursion 递归
    global COUNT
    COUNT += 1
    print(COUNT)
    func()
查看递归层数

*****解耦 *****

要完成一个完整的功能,但这个功能的规模要尽量小,并且和这个功能无关的其他代码应该和这个函数分离
    1.增强代码的重用性
    2.减少代码变更的相互影响

什么是递归 #recursion 递归
    一个函数在内部调用自己
    递归的层数在python里是有限制的

递归效率低,需要在进入下一递归时保留当前的状态.

1.1必须有一个明确的结束条件

1.2每进入更深一次递归,问题规模相比上次递归都应该有所减少

l=[1,[2,3,[4,5,[6,7,[8,9,[10,11,[12,13]]]]]]]
def func(l):
    for i in l:
        if isinstance(i,list):
            func(i)
        else:
            print(i)

func(l)
列表递归

递归实例一:简单年龄

敲两遍  就看懂了    我是不是快成神了    
你说你不懂怎么办?   那更好办 敲20遍  还不懂? 神不需要理解凡尘


#写递归函数必须要有一个结束条件   这是先决条件
#alex
#alex比egon大两岁 +2
#egon比wushi大两岁 +2
#wushi比金鑫大两岁 +2
#金鑫40了

def age(n):
    if n ==4:
        return 40
    return age(n+1)+2# 关键点在于这个return 返回的值是返回给他自身调用的自己而不是返回给age() 而是返回给age()+2
        #这里还有一个关键点就是 return返回自己调用自己的结果时 可以加上附加条件(就是自己想要计算的)
print(age(1)) #结果为42

# def age(n):
#     if n==4:
#         return 40
#     return age(n+1)+2

#递归分为两部曲(递+归)
#以下是递 加归
# def age(1):
#     return age(2)+2 #相当于44+2=46
#
# def age(2):
#     return age(3)+2 #相当于42+2=44
#
# def age(3):
#     return age(4)+2 #相当于40+2=42
#
# def age(4):
#     if 4==4:
#         return 40#返回给调用者上层函数

递归实例二:简单数字阶乘

递归不难就是看你肯不肯去倒腾了



#求阶乘 n = 7  7*6*5*4*3*2*1
def func(n):
    if n == 1:
        return 1
    else:
        return n*func(n-1)

ret = func(4)
print(ret)

# #n = 4
# def func(4):
#     return 4*(4-1) n=3 2*(4-1)*4=24 
#
# #n = 3
# def func(3):
#     return 3*(3-1) n=2   1*(3-1)
#
# #n = 2
# def func(2):
#         return 2 2*(2-1) n=1  1*(2-1)
#
# #n = 1
# def func(n):
#     if n == 1:
#         return 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]

def func(l,aim):
    mid = (len(l)-1)//2
    if l:
        if aim > l[mid]:
            func(l[mid+1:],aim)
        elif aim < l[mid]:
            func(l[:mid],aim)
        elif aim == l[mid]:
            print("bingo",mid)
    else:
        print('找不到')
func(l,66)
func(l,6)
二分法
# list.sort()将列表进行有序化排列
# def search(num ,l ,start=None,end=None):
#定义函数()内写 要找寻的数字,数字所在的列表,开始查找的数字,查找结束的数字
#     start=start if start else 0
#     end = end if end else len(l)-1
#     mid = (end-start)//2+start
#默认开始值是0 结束值列表索引最后一位  中间值为末尾减去开始得的值除以2 加上开始的值
#     if l[mid]>num:
#         search(num,l,start,mid-1)
#     elif l[mid]<num:
#         search(num,l,mid+1,end)
#     elif l[mid]==num:
#         print(mid,l[mid])
#判断阶段分为3种 大于小于 等于    每一次的判断 找寻的数字 和列表不变 但是开始查找的数字和结束的数字会根据判断条件改变
# 直到找到查找的值
# 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]
# search(66,l)









def search(num,l,start=None,end=None): #66,[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]
    start = start if start else 0      #start = 0
    end = end if end else len(l) - 1   #end = 24
    mid = (end - start)//2 + start     #mid = 12
    if l[mid] > num :                  #l[mid] = 41  <  66
        search(num,l,start,mid-1)
    elif l[mid] < num:
        ret = search(num,l,mid+1,end)        #search(66,l,13,24)
        return ret
    elif l[mid] == num:
        return mid, l[mid]

def search(num,l,start=None,end=None): #66,[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]
    start = start if start else 0      #start = 13
    end = end if end else len(l) - 1   #end = 24
    mid = (end - start)//2 + start     #mid = 18
    if l[mid] > num :                  #l[mid] = 67  >  66
        search(num,l,start,mid-1)      #search(66,l,13,17)
    elif l[mid] < num:
        ret = search(num,l,mid+1,end)
        return ret
    elif l[mid] == num:
        return mid, l[mid]

def search(num,l,start=None,end=None): #66,[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]
    start = start if start else 0      #start = 13
    end = end if end else len(l) - 1   #end = 17
    mid = (end - start)//2 + start     #mid = 15
    if l[mid] > num :                  #l[mid] = 56  <  66
        search(num,l,start,mid-1)
    elif l[mid] < num:
        ret = search(num,l,mid+1,end)        #search(66,l,16,17)
        return ret
    elif l[mid] == num:
        return mid, l[mid]

def search(num,l,start=None,end=None): #66,[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]
    start = start if start else 0      #start = 16
    end = end if end else len(l) - 1   #end = 17
    mid = (end - start)//2 + start     #mid = 16
    if l[mid] > num :                  #l[mid] = 56  <  66
        search(num,l,start,mid-1)
    elif l[mid] < num:
        ret = search(num,l,mid+1,end)        #search(66,l,17,17)
        return ret
    elif l[mid] == num:
        return mid, l[mid]

def search(num,l,start=None,end=None): #66,[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]
    start = start if start else 0      #start = 17
    end = end if end else len(l) - 1   #end = 17
    mid = (end - start)//2 + start     #mid = 17
    if l[mid] > num :                  #l[mid] = 66  ==  66
        search(num,l,start,mid-1)
    elif l[mid] < num:
        search(num,l,mid+1,end)
    elif l[mid] == num:
        return mid, l[mid]               #return 17,66
二分法(2)慎点

二分查找方法(升级版)

def func(l, aim,start = 0,end = len(l)-1 ):
    mid = (start+end)//2
    if not l[start:end+1]:
        return
    elif aim > l[mid]:
        return func(l,aim,mid+1,end)
    elif aim < l[mid]:
        return func(l,aim,start,mid-1)
    elif aim == l[mid]:
        print("bingo")
        return mid

index = func(l,68)
print(index)
升级版

递归编写三级菜单

menu = {
    '北京': {
        '海淀': {
            '五道口': {
                'soho': {},
                '网易': {},
                'google': {}
            },
            '中关村': {
                '爱奇艺': {},
                '汽车之家': {},
                'youku': {},
            },
            '上地': {
                '百度': {},
            },
        },
        '昌平': {
            '沙河': {
                '老男孩': {},
                '北航': {},
            },
            '天通苑': {},
            '回龙观': {},
        },
        '朝阳': {},
        '东城': {},
    },
    '上海': {
        '闵行': {
            "人民广场": {
                '炸鸡店': {}
            }
        },
        '闸北': {
            '火车战': {
                '携程': {}
            }
        },
        '浦东': {},
    },
    '山东': {},
}

def threeLM(menu):
    while True:
        for key in menu:
            print(key)
        k = input(">>>")
        if k in menu:
            threeLM(menu[k])

threeLM(menu)
只实现功能,没有前进后退
menu = {
    '北京': {
        '海淀': {
            '五道口': {
                'soho': {},
                '网易': {},
                'google': {}
            },
            '中关村': {
                '爱奇艺': {},
                '汽车之家': {},
                'youku': {},
            },
            '上地': {
                '百度': {},
            },
        },
        '昌平': {
            '沙河': {
                '老男孩': {},
                '北航': {},
            },
            '天通苑': {},
            '回龙观': {},
        },
        '朝阳': {},
        '东城': {},
    },
    '上海': {
        '闵行': {
            "人民广场": {
                '炸鸡店': {}
            }
        },
        '闸北': {
            '火车战': {
                '携程': {}
            }
        },
        '浦东': {},
    },
    '山东': {},
}
#相同的数据类型 嵌套在一起
# def Three_Level_Menu(menu):
#     while True:
#         for k in menu:print(k)
#         key = input('>>>')
#         if key == 'q':return 'q'
#         elif key == 'b':break
#         elif key in menu:
#             ret = Three_Level_Menu(menu[key])
#             if ret == 'q': return 'q'
# Three_Level_Menu(menu)
完美版
原文地址:https://www.cnblogs.com/zgd1234/p/7265128.html