递归函数

递归函数:

  定义:在函数中调用自身函数就是递归函数 

  #如果递归次数太多,就不适用递归来解决问题

            #缺点:占内存
            #优点:会让代码变简单

  递归的最大深度——997 :递归函数如果不受到外力的阻止会一直执行下去。但是每一次函数调用都会产生一个属于它自己的名称空间,如果一直调用下去,就会造成名称空间占用太多内存的问题,于是python为了杜绝此类现象,强制的将递归层数控制在了997,超出997就会提示一下报错内容:

       RecursionError:递归错误,超过了递归的最大深度

def foo(n):
    print(n)
    n += 1
    foo(n)
foo(1)


#结果:
997
Traceback (most recent call last):
  File "/Users/yaoyeshiguang/PycharmProjects/S9/day2/ceshi.py", line 79, in <module>
    foo(1)
  File "/Users/yaoyeshiguang/PycharmProjects/S9/day2/ceshi.py", line 77, in foo
    foo(n)
  File "/Users/yaoyeshiguang/PycharmProjects/S9/day2/ceshi.py", line 77, in foo
    foo(n)
  File "/Users/yaoyeshiguang/PycharmProjects/S9/day2/ceshi.py", line 77, in foo
    foo(n)
  [Previous line repeated 993 more times]
  File "/Users/yaoyeshiguang/PycharmProjects/S9/day2/ceshi.py", line 75, in foo
    print(n)
RecursionError: maximum recursion depth exceeded while calling a Python object
验证‘997理论’测试最大递归深度

997是python为了程序的内存优化所设定的一个默认值,也可以取调整修改该默认值:

#修改递归最大深度为10w
import sys
print(sys.setrecursionlimit(100000))
import sys
sys.setrecursionlimit(1000000)
n = 0
def story():
    global n
    n += 1
    print(n)
    story()

story()


#结果:
...
34939
34940
34941
测试调整后的递归深度

注:实际可以达到的深度取决于计算机的性能!

  实例演示:

      有四个数,其中第一个为10,第二个比第一个多2,第三个比第二个多2,第四个比第三个多2,问第四个数是多少

#分析规律
a(3) = a(2) + 2
a(2) = a(1) + 2
a(1) = a + 2
a = 10

函数实现如下:

def a(n):
    if n == 1:
        return 10
    else:
        return a(n-1)+2

print(a(4))    #结果16

#代码拆分理解
#a(4) 调用函数a并传入参数4,函数运行结果为return a(4-1)+2,此时尚未等到return返回值再次调用函数a(4-1)即a(3)...以此类推,直至a(1),n接收的传入参数为1时,满足条件if n==1:执行return 10,此时10作为返回值返给调用函数a(1)即a(2-1)、、、以此类推,逐层将值进行返还,直至a(4)层级,此时结果为10+2+2+2等于16
递归函数应用

  实例进阶

    递归函数与三级菜单

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


def threeLM(dic):
    while True:
        for k in dic:print(k)
        key = input('input>>').strip()
        if key == 'b' or key == 'q':return key
        elif key in dic.keys() and dic[key]:
            ret = threeLM(dic[key])
            if ret == 'q':return 'q'
        elif (not dic.get(key)) or (not dic[key]):
            continue

threeLM(menu)
三级菜单

 

递归函数与二分查找法

  二分查找法,必须处理有序的列表

  示例:

    现有列表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],假设index查找方法不能使用,由于列表内元素过多,使用for循环效率过低,这时二分查找法就登场了!假设目标为66,先来看一下分析过程:

这个过程就是二分查找法,代码落实如下:

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)
二分法基础版
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   # //2 为除2取整数部分
    if start > end:
        return None
    elif l[mid] > num :
        return search(num,l,start,mid-1)
    elif l[mid] < num:
        return search(num,l,mid+1,end)
    elif l[mid] == num:
        return mid
二分算法进阶终极版

 

posted @ 2018-01-08 15:52  摇曳时光  阅读(211)  评论(0编辑  收藏  举报