Python—递归函数

楔子html

在讲今天的内容以前,咱们先来说一个故事,讲的什么呢?从前有座山,山里有座庙,庙里有个老和尚讲故事,讲的什么呢?从前有座山,山里有座庙,庙里有个老和尚讲故事,讲的什么呢?从前有座山,山里有座庙,庙里有个老和尚讲故事,讲的什么呢?从前有座山,山里有座庙,庙里有个老和尚讲故事,讲的什么呢......这个故事大家不喊停我能讲一天!咱们说,生活中的例子也能被写成程序,刚刚这个故事,让大家写,大家怎么写呀?python

while True: story = "  从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? " print(story)

你确定是要这么写的,可是,如今咱们已经学了函数了,什么东西都要放到函数里去调用、执行。因而你确定会说,我就这么写:算法

def story(): s = """ 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? """ print(s) while True: story()

可是你们来看看,我是怎么写的!app

def story(): s = """ 从前有个山,山里有座庙,庙里老和尚讲故事, 讲的什么呢? """ print(s) story() story()

先无论函数最后的报错,除了报错以外,咱们能看的出来,这一段代码和上面的代码执行效果是同样的。ide

初识递归

递归的定义——在一个函数里再调用这个函数自己函数

如今咱们已经大概知道刚刚讲的story函数作了什么,就是在一个函数里再调用这个函数自己,这种魔性的使用函数的方式就叫作递归性能

刚刚咱们就已经写了一个最简单的递归函数。学习

递归的最大深度——997优化

正如大家刚刚看到的,递归函数若是不受到外力的阻止会一直执行下去。可是咱们以前已经说过关于函数调用的问题,每一次函数调用都会产生一个属于它本身的名称空间,若是一直调用下去,就会形成名称空间占用太多内存的问题,因而python为了杜绝此类现象,强制的将递归层数控制在了997(只要997!你买不了吃亏,买不了上当...).google

拿什么来证实这个“997理论”呢?这里咱们能够作一个实验:

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

由此咱们能够看出,未报错以前能看到的最大数字就是997.固然了,997是python为了咱们程序的内存优化所设定的一个默认值,咱们固然还能够经过一些手段去修改它:

import sys print(sys.setrecursionlimit(100000))

咱们能够经过这种方式来修改递归的最大深度,刚刚咱们将python容许的递归深度设置为了10w,至于实际能够达到的深度就取决于计算机的性能了。不过咱们仍是不推荐修改这个默认的递归深度,由于若是用997层递归都没有解决的问题要么是不适合使用递归来解决要么是你代码写的太烂了~~~

看到这里,你可能会以为递归也并非多么好的东西,不如while True好用呢!然而,江湖上流传这这样一句话叫作:人理解循环,神理解递归。因此你可别小看了递归函数,不少人被拦在大神的门槛外这么多年,就是由于没能领悟递归的真谛。并且以后咱们学习的不少算法都会和递归有关系。来吧,只有学会了才有资本嫌弃!

再谈递归

这里咱们又要举个例子来讲明递归能作的事情。

例一:

如今大家问我,alex老师多大了?我说我不告诉你,但alex比 egon 大两岁。

你想知道alex多大,你是否是还得去问egon?egon说,我也不告诉你,但我比武sir大两岁。

你又问武sir,武sir也不告诉你,他说他比金鑫大两岁。

那你问金鑫,金鑫告诉你,他40了。。。

这个时候你是否是就知道了?alex多大?

1 金鑫   40
2 武sir   42
3 egon   44
4 alex    46

你为何能知道的?

首先,你是否是问alex的年龄,结果又找到egon、武sir、金鑫,你挨个儿问过去,一直到拿到一个确切的答案,而后顺着这条线再找回来,才获得最终alex的年龄。这个过程已经很是接近递归的思想。咱们就来具体的我分析一下,这几我的之间的规律。

age(4) = age(3) + 2 
age(3) = age(2) + 2 age(2) = age(1) + 2 age(1) = 40

那这样的状况下,咱们的函数应该怎么写呢?

def age(n): if n == 1: return 40 else: return age(n-1)+2 print(age(4))

递归函数与三级菜单

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

threeLM(menu)
递归函数实现三级菜单

还记得以前写过的三级菜单做业么?如今我们用递归来写一下~

l = [menu]
while l:
    for key in l[-1]:print(key)
    k = input('input>>').strip()   # 北京
    if k in l[-1].keys() and l[-1][k]:l.append(l[-1][k])
    elif k == 'b':l.pop()
    elif k == 'q':break
堆栈实现

递归函数与二分查找算法

http://www.cnblogs.com/Eva-J/articles/7197403.html

相关文章
相关标签/搜索