举例学习Python中的递归函数

320 阅读7分钟

递归是指一个函数在自己的代码中调用自己的过程。你可以把它看作是完成一个循环结构的另一种方式。递归模式出现在现实世界的许多场景中,我们将在这里介绍一些 Python 中递归的例子。一个递归函数只是不断地调用自己,直到完成手头的问题。这带来了一个很好的观点,那就是要确保你的递归函数实际上在某个时刻终止并返回。否则,递归函数将永远运行,耗尽你的内存,并使你的计算机崩溃。有一个函数实际结束的步骤被称为中断条件。每次调用递归函数时,前一次调用的参数值都会存储在调用栈中。

递归实例1:向后数2

这里我们有一个名为backwardsby2的函数,它从一个初始数字开始,用2的步长来打印数字的倒序。破解条件是如果该数字小于或等于零。在这种情况下,我们只需打印 "零 "即可。如果不满足这个条件,该函数将使用当前的数字-2来调用自己。我们还初始化了一个列表,并添加了一个等于当前数字的笑脸表情符号。这样一来,随着倒数的发生,每次迭代都会出现相应数量的表情符号笑脸。我想你会同意,这是这个递归例子的一个重要特征。

def backwardsby2(num):
    if num <= 0:
        print('Zero!')
        return
    else:
        emojismiles = []
        for i in range(0, num):
            emojismiles += '😃'
        print(num, ' '.join(emojismiles))
        backwardsby2(num - 2)


backwardsby2(9)
9 😃 😃 😃 😃 😃 😃 😃 😃 😃
7 😃 😃 😃 😃 😃 😃 😃
5 😃 😃 😃 😃 😃
3 😃 😃 😃
1 😃
Zero!

递归实例2:河内塔

河内塔是一个古老的谜题,据说起源于印度或越南。它涉及到在三根柱子上移动各种大小的圆环或圆盘。这个谜题的目标是将一个柱子上的所有圆环移到另一个柱子上,同时保持圆环的顺序不变。但是,你必须遵守谜题的规则,即每次只能移动一个权利,而且不能将环放在一个较小的环上面。这个谜题可以用Python中的递归来解决,所以让我们来看看它的实际效果吧!

def towerOfHanoi(numrings, from_pole, to_pole, aux_pole):
    if numrings == 1:
        print('Move ring 1 from', from_pole, 'pole to', to_pole, 'pole')
        return
    towerOfHanoi(numrings - 1, from_pole, aux_pole, to_pole)
    print('Move ring', numrings, 'from', from_pole, 'pole to', to_pole, 'pole')
    towerOfHanoi(numrings - 1, aux_pole, to_pole, from_pole)


numrings = 2
towerOfHanoi(numrings, 'Left', 'Right', 'Middle')
Move ring 1 from Left pole to Middle pole
Move ring 2 from Left pole to Right pole
Move ring 1 from Middle pole to Right pole

上面的输出显示了只有两个环时的步骤数。我们可以在使用三个环的情况下再次运行程序,你会发现解决河内塔的步骤数在增长。此外,你可以在可视化中查看过程中的每一步。

numrings = 3
towerOfHanoi(numrings, 'Left', 'Right', 'Middle')
Move ring 1 from Left pole to Right pole
Move ring 2 from Left pole to Middle pole
Move ring 1 from Right pole to Middle pole
Move ring 3 from Left pole to Right pole
Move ring 1 from Middle pole to Left pole
Move ring 2 from Middle pole to Right pole
Move ring 1 from Left pole to Right pole


河内塔的起始状态
tower of hanoi step 1


将环1从左极移至右极
step 2 tower of hanoi


将环2从左极移至中极
tower of hanoi step 3


将1号环从右杆移到中杆
step 4 tower of hanoi


将3号环从左杆移到右杆
tower of hanoi step 5


将1号环从中间杆移至左杆
step 6 tower of hanoi


将2号环从中间杆移至右杆
tower of hanoi step 7


将环1从左极移到右极
tower of hanoi is complete


递归实例3:将一个数字设为一个幂数

我们可以使用递归来创建一个函数,计算一个数字乘以自己一定次数的值。当然,你已经看过很多次了。在数学中,将一个数字设为一个数字的幂,这是一个常见的操作。例如,2的四次方是16,2的五次方是32,以此类推。我们想把一个参数乘以一定的倍数。这意味着我们需要两个参数,一个是数字本身,另一个是它将被设置为的幂。破解条件是如果 **topwr**变量为零。这意味着我们已经完成了所有需要的乘法运算。正是这个函数递归调用自己的事实提供了一个循环行为。

def power(num, topwr):
    if topwr == 0:
        return 1
    else:
        return num * power(num, topwr - 1)


print('{} to the power of {} is {}'.format(4, 7, power(4, 7)))
print('{} to the power of {} is {}'.format(2, 8, power(2, 8)))
4 to the power of 7 is 16384
2 to the power of 8 is 256


递归实例4:阶乘函数

阶乘是将所有小于或等于一个给定数的整数相乘的过程。所以,5!相当于5*4*3*2*1,就是120。我们可以使用一个递归函数来为我们做这项工作。它只需要一个参数,即我们要应用阶乘的数字。对于突破条件,如果给定的参数已经达到零,我们就返回1的值。否则,我们返回数字乘以阶乘并递减数字值。

def factorial(num):
    if (num == 0):
        return 1
    else:
        return num * factorial(num - 1)


print('{}! is {}'.format(4, factorial(4)))
print('{}! is {}'.format(2, factorial(2)))
4! is 24
2! is 2

递归实例 5: 斐波那契数列

斐波那契数列在世界和所有自然界中随处可见。0、1、1、2、3、5、8、13、21、34等等的序列就是斐波那契序列。每一个连续的数字都是由前面的两个数字相加而得。下面是我们在 Python 中使用递归函数计算斐波那契数列的方法。它使用这个过程。

  • 如果数字是0,那么答案就是0。
  • 如果这个数字是1,那么答案就是1。
  • 否则,答案就是前两个斐波那契数字的总和。
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)


number = 14

print('Fibonacci sequence:')
for i in range(number):
    print(fibonacci(i))
Fibonacci sequence:
0
1
1
2
3
5
8
13
21
34
55
89
144
233

递归例6:从1到n的数字之和

我们可以用递归来找出从1到n的数字之和,如1+2+3+4+,等等。

def sumnums(n):
    if n == 1:
        return 1
    return n + sumnums(n - 1)


print(sumnums(3))
print(sumnums(6))
print(sumnums(9))
6
21
45

递归实例7:反转一个字符串

这个例子很有趣。这里有反转字符串的递归函数,还有一些非常有趣的字符串,反转后会产生意想不到的结果

def reverse(string):
    if len(string) == 0:
        return string
    else:
        return reverse(string[1:]) + string[0]


reverseme = 'Desserts'
print(reverse(reverseme))

reverseme = 'Knits'
print(reverse(reverseme))

reverseme = 'Regal'
print(reverse(reverseme))

reverseme = 'Pupils'
print(reverse(reverseme))

reverseme = 'Smart'
print(reverse(reverseme))

reverseme = 'Pals'
print(reverse(reverseme))

reverseme = 'Straw'
print(reverse(reverseme))

reverseme = 'Time'
print(reverse(reverseme))

reverseme = 'Star'
print(reverse(reverseme))
stresseD
stinK
lageR
slipuP
tramS
slaP
wartS
emiT
ratS

Python 递归实例总结

递归函数直接或间接地调用自己,从而形成一个循环。这种循环一直持续到满足一个中断条件为止。它们可以被用来遍历任意形状的结构,或者用于一般的迭代。Python 支持递归,尽管在许多情况下它不一定是最简单或最有效的方法。在本教程中,我们看到了 Python 中递归的几个例子。把这些片段放在你的 IDE 中,在改变函数所提供的参数时对它们进行测试。这将有助于更好地理解它们如何工作。递归函数有一些需要注意的缺点。递归函数可能是低效的,因为它们占用了大量的内存和时间。除此之外,有时递归背后的逻辑很难遵循,使得调试问题很困难。