递归:自己调用自己。需要递归出口返回。
def fact(n): # 阶乘
if n == 0:
return 1
else:
return n * fact(n-1)
print(fact(3))
调用栈,每次递归都会分配新的内存,类似于调用栈。
"""打印1到10序列"""
def print_num_recursive(n):
if n > 0:
print_num_recursive(n-1)
print(n)
print_num_recursive(10)
递归每次执行就会压栈,打印没有执行,继续调用自己,压完栈才打印。
我们来用栈模拟下递归:
from collections import deque
class Stack(object):
def __init__(self):
self._deque = deque()
def push(self, value):
return self._deque.append(value)
def pop(self):
return self._deque.pop()
def is_empty(self):
return len(self._deque) == 0
def print_num_use_stack(n):
s = Stack()
while n > 0:
s.push(n)
n -= 1
while not s.is_empty():
print(s.pop())
print_num_use_stack(10)
尾递归: 递归的调用放在函数结尾。尾递归可以避免爆栈。
其他语言有尾递归优化,但是python默认不支持尾递归。
递归举例:汉诺塔移动。
n个盘子和三个杆,源杆(source),目标杆(dest),中介杆(intermediate)
把上面n-1个盘子从S移动到I,借助D杆
把最底下的盘子从S移动到D。
把n-1个盘子从I移动到D,借助S
def hanoi_move(n, source, dest, intermediate):
# n是盘子数,第一个参数是起始,第二个参数是目标,第三个是借助
if n >= 1:
hanoi_move(n - 1, source, intermediate, dest)
print("Move %s --> %s" % (source, dest))
hanoi_move(n - 1, intermediate, dest, source)
hanoi_move(3, 'A', 'C', 'B')
详细理解:
开始是 move(n,s,d,i)
然后是move(n-1,s,i,d) 说明:s移动n-1个盘子到i上,
然后打印(n, s–>d) 说明:就是把s最下面放到d上去,
move(n-1,i,d,s) 说明:然后把n-1 从中间i,移到d,借助的s。