递归简单来说就是一个函数自己调用自己。必须遵循的3个原则是:
- 必须有基本情况
- 必须改变其状态并向基本情况靠近
- 必须调用自己
举例:进制转换
因为递归刚好有一个倒序的过程,所以可以用栈考虑的都可以用递归考虑。
def convert2base(n, base):
convert_str = "0123456789ABCDEF"
if n < base:
return convert_str[n]
else:
return convert2base(n // base, base) + convert_str[n % base]
举例:回型绘图
turtle库
from turtle import *
def drawSpiral(my_turtle, line_len):
if line_len > 0:
my_turtle.forward(line_len)
my_turtle.right(90)
drawSpiral(my_turtle, line_len - 5)
if __name__ == "__main__":
my_turtle = Turtle()
my_screen = my_turtle.getscreen()
drawSpiral(my_turtle, 100)
my_screen.exitonclick() # 点击即可退出
举例:分形树
def tree(branch_len, t):
if branch_len > 5:
t.forward(branch_len) # 前进
t.right(20) # 右转20度
tree(branch_len - 15, t)
t.left(40) # 为了画左子树,转多一些
tree(branch_len - 15, t)
t.right(20) # 画完转回去,后退
t.backward(branch_len)
if __name__ == "__main__":
my_turtle = Turtle()
my_screen = my_turtle.getscreen()
my_turtle.left(90) # 先向左转90度
my_turtle.up() # 抬起画笔,不绘制
my_turtle.backward(300) # 向海龟朝向相反的方向,走300。其实就是后退
my_turtle.down() # 放下画笔,开始绘制
my_turtle.color('green') # 设置颜色
tree(100, my_turtle) # 开始画树
my_screen.exitonclick()
Sierpinski三角
from turtle import *
def drawTriangle(points, color, my_turtle):
my_turtle.fillcolor(color)
my_turtle.up()
my_turtle.goto(points[0])
my_turtle.down()
my_turtle.begin_fill()
my_turtle.goto(points[1])
my_turtle.goto(points[2])
my_turtle.goto(points[0])
my_turtle.end_fill()
def getMid(p1, p2):
return ((p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2)
def sierpinski(points, degree, my_turtle):
colormap = ['blue', 'red', 'green', 'white', 'yellow', 'violet', 'orange']
drawTriangle(points, colormap[degree], my_turtle)
if degree > 0:
sierpinski([points[0], getMid(points[0], points[1]),
getMid(points[0], points[2])], degree - 1, my_turtle)
sierpinski([points[1], getMid(points[0], points[1]),
getMid(points[1], points[2])], degree - 1, my_turtle)
sierpinski([points[2], getMid(points[2], points[1]),
getMid(points[0], points[2])], degree - 1, my_turtle)
if __name__ == "__main__":
my_turtle = Turtle()
my_screen = my_turtle.getscreen()
my_points = [(-100, -150), (0, 50), (100, -150)]
sierpinski(my_points, 5, my_turtle)
my_screen.exitonclick()
汉诺塔问题
描述:有三根柱子和N个叠好的盘子。上面的盘子小,下面的盘子大。现在第一根上放好了盘子,要求将所有盘子移动到第三根上,并满足:1)每次只能移动一个盘子;2)大盘子必须在小盘子下面
def moveDisk(fp, tp):
print("move 1 disk: " + fp + "→" + tp)
def moveTower(height, fp, tp, mid):
if height >= 1:
# 先将height-1个从fp移到mid, 途中可以使用tp
moveTower(height - 1, fp, mid, tp)
# 将一个盘子,从fp移动到tp
moveDisk(fp, tp)
# 最后把height-1个从mid移到tp,途中可以使用fp
moveTower(height - 1, mid, tp, fp)
if __name__ == "__main__":
moveTower(3, "1", "3", "2")
'''
move 1 disk: 1→3
move 1 disk: 1→2
move 1 disk: 3→2
move 1 disk: 1→3
move 1 disk: 2→1
move 1 disk: 2→3
move 1 disk: 1→3
'''
589. N 叉树的前序遍历
https://leetcode.cn/problems/n-ary-tree-preorder-traversal/
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution:
def __init__(self):
self.ans = []
def traverse(self, root: 'Node'):
if root == None:
return
self.ans.append(root.val)
for child in root.children:
self.traverse(child)
def preorder(self, root: 'Node') -> List[int]:
self.traverse(root)
return self.ans