python编写递归函数_python之路——递归函数

本文深入探讨了递归的概念,通过一个无限循环的故事引出递归的定义,即在一个函数内部调用自身。讲解了Python中递归的最大深度限制为997,并展示了如何修改这个限制。接着,通过年龄推算的例子阐述了递归的思维方式,并用递归实现了三级菜单和二分查找算法,强调递归在解决问题中的独特优势。递归虽然看似复杂,但在理解和掌握后,对于解决某些问题有着不可替代的作用。
摘要由CSDN通过智能技术生成

阅读目录

楔子

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

whileTrue:

story= "从前有个山,山里有座庙,庙里老和尚讲故事,

讲的什么呢?" print(story)

你肯定是要这么写的,但是,现在我们已经学了函数了,什么东西都要放到函数里去调用、执行。于是你肯定会说,我就这么写:

defstory():

s= """从前有个山,山里有座庙,庙里老和尚讲故事,

讲的什么呢?"""

print(s)whileTrue:

story()

但是大家来看看,我是怎么写的!

defstory():

s= """从前有个山,山里有座庙,庙里老和尚讲故事,

讲的什么呢?"""

print(s)

story()

story()

先不管函数最后的报错,除了报错之外,我们能看的出来,这一段代码和上面的代码执行效果是一样的。

初识递归

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

现在我们已经大概知道刚刚讲的story函数做了什么,就是在一个函数里再调用这个函数本身,这种魔性的使用函数的方式就叫做递归。

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

递归的最大深度——997

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

拿什么来证明这个“997理论”呢?这里我们可以做一个实验:

ContractedBlock.gif

ExpandedBlockStart.gif

deffoo(n):print(n)

n+= 1foo(n)

foo(1)

测试最大递归深度

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

ContractedBlock.gif

ExpandedBlockStart.gif

importsysprint(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) + 2age(3) = age(2) + 2age(2) = age(1) + 2age(1) = 40

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

defage(n):if n == 1:return 40

else:return age(n-1)+2

print(age(4))

递归函数与三级菜单

ContractedBlock.gif

ExpandedBlockStart.gif

menu ={'北京': {'海淀': {'五道口': {'soho': {},'网易': {},'google': {}

},'中关村': {'爱奇艺': {},'汽车之家': {},'youku': {},

},'上地': {'百度': {},

},

},'昌平': {'沙河': {'老男孩': {},'北航': {},

},'天通苑': {},'回龙观': {},

},'朝阳': {},'东城': {},

},'上海': {'闵行': {"人民广场": {'炸鸡店': {}

}

},'闸北': {'火车战': {'携程': {}

}

},'浦东': {},

},'山东': {},

}

menu

ContractedBlock.gif

ExpandedBlockStart.gif

1 defthreeLM(dic):2 whileTrue:3 for k in dic:print(k)4 key = input('input>>').strip()5 if key == 'b' or key == 'q':returnkey6 elif key in dic.keys() anddic[key]:7 ret =threeLM(dic[key])8 if ret == 'q': return 'q'

9

10 threeLM(menu)

递归函数实现三级菜单

还记得之前写过的三级菜单作业么?现在咱们用递归来写一下~

ContractedBlock.gif

ExpandedBlockStart.gif

l =[menu]whilel: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

堆栈实现

递归函数与二分查找算法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值