递归程序设计是计算机算法设计的重要组成部分,是衡量程序设计水平的关键指标。递归程序应用十分广泛,如数据结构中树、图、快速排序等核心算法。然而,递归程序的学习并非易事,要求较高的抽象思维和逻辑思维,即便是拥有多年开发经验的资深工程师,依然会“谈归色变”。
介绍递归的博客众多,然而初学者在阅读后,依然不知所措,复杂的概念、复杂的递归树、复杂的思想,让大家望而却步,亟需新的思路来重新梳理递归的本质。
本系列博客将介绍递归的方方面面有趣的知识点和案例,由浅入深,试图从各个视角来深入理解递归,最终实现活运用递归解决实际问题。
问题
所谓递归,指的就是某函数foo不停的调用自身,直到满足某条件后结束调用自己,如下:
def foo(): if condition is true: return do some interesting things foo()
不难发现,foo()函数一直在不停的在调用自己,而每一次调用自己,[do some interesting things] 这块代码都会被执行一次,因此,递归可以理解为重复的在执行一段有趣的代码,递归调用了n次,则这段有趣代码就被执行了n次。
如果单就这一点来看,递归的功能与循环结构十分类似,如下是循环结构的一般模式:
for i in range(n): do some interesting things
基于上述认识,可以利用递归来实现循环结构能够做的一些事情。
方法
利用递归实现100次打印字符串’hello’,即print(‘hello’)的代码需要重复执行100次。利用递归的重复执行[do some interesting things]特性,可以实现该功能,关键点在于如何精确的控制递归执行的次数。
定义变量n,每调用一次自身就减少1,这样即可实现控制递归执行的次数,代码如下:
def foo(n): if n == 0: return print('hello') foo(n-1) if __name__ == '__main__': foo(100)
结语
本节介绍了递归的重复执行代码块的特性,并通过精确控制递归调用的次数,实现了一种重复打印字符串的效果。是不是觉得很有趣呢?当深入理解递归后,并充分利用其特性,可以实现一些十分有趣的功能。
递归,还有太多的细节值得我们去发掘,如果您对递归感兴趣,欢迎持续关注后续递归算法系列博客。