我们上次学到了选择排序的算法,通过学习我们对python中的算法有了一个初步的了解,我们再来学习一种我们在python中非常常用和重要的算法----递归,之前我们也通过斐波那契数列来简单的了解过递归
回顾递归函数之斐波那契数列
但是我们得明白,递归只是让我们解决问题的方法更加的清晰,但是并没有在性能上的优势!
递归算法
我们还是以案例来介绍:我们有一堆的盒子,打开一个盒子我们可能会找到我们需要的钥匙,但是也可能盒子中是另一个盒子,我们想要找到钥匙,有几种解决的办法呢?
方法一:使用while循环
创建一个盒子堆,从盒子堆中找到一个盒子,如果盒子里是盒子则将盒子加入到盒子堆中,若找到的是钥匙,则输出结束
方法二:使用递归的思路进行解决
创建一个盒子堆,所有的盒子相当于第一部分的盒子,将所有的盒子打开查看,若找到钥匙则输出结束,若没找到钥匙开出的盒子相当于第二部分的盒子,返回第一步用同样的方法和思路去查看第二部分的盒子,依次类推,直到找到钥匙输出结束
这里我么还得了解一个概念----基线条件和递归条件
基线条件和递归条件
在使用递归的时候,我们为了避免无限循环的情况,每个递归都是有两个部分组成:基线条件(base case)和递归条件(recursive case),递归条件是函数调用自己,而基线条件是为了避免形成无限循环
这里我写了一个简单的数字倒数来进行理解:
def num_daoshu(num): # 这个参数是从几开始倒数
print(num) # 输出这个数字
if num <= 0: # 基线条件
return
else: # 递归条件
return num_daoshu(num - 1)
print(num_daoshu(5))
栈
栈是一种简单的数据结构栈采用先进后出或者是后进先出的方式存储数据,栈中数据的插入删除操作都是在栈顶端进行
在递归函数中调用栈:
还是盒子堆中找钥匙的例子,我们有A和B两个盒子,我们打开A发现了盒子C,打开C,我们发现C是空的,因此我们去返回去打开盒子B…知道找到钥匙
递归调用栈就类似于这样
栈的缺点:
使用栈虽然方便,但是在存储相近的信息可能占用大量的内存,每个函数调用都会占用一定的内存,因此我们的栈会累计的很高,计算机存储了大量的函数调用的信息,
这种情况我们有两种解决办法:
1.重新编码,转而使用循环
2.使用尾循环(这是一个高级递归主题暂时忽略),并且不是每种语言都支持尾循环