递归三部曲:
1. 确定递归函数的参数和返回值
返回值一般是没有的,因为结果直接放在参数里了
参数:根节点,vector里面存元素
2. 确定终止条件
深度优先遍历,如果current is None,就return,往上再找
一定要确定终止条件,否则可能会栈溢出
3. 确定单层递归的逻辑
前序、中序、后序,不同。
前序 preorder:中左右
中序 inorder :左中右
后续 postorder:左右中
前中后序,代码:
前序 (LeetCode 144):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
res = []
def dfs(node):
if not node:
return
res.append(node.val)
dfs(node.left)
dfs(node.right)
dfs(root)
return res
先把根节点加入,然后遍历左子树,还是用同样的逻辑去遍历,所以可以用递归函数。
最后记得调用dfs(root),这样才开始遍历树
最后返回res即可。
中序 (LeetCode 94):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res = []
def dfs(node):
if not node:
return
dfs(node.left)
res.append(node.val)
dfs(node.right)
dfs(root)
return res
后序 (LeetCode 144):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res = []
def dfs(node):
if not node:
return
dfs(node.left)
dfs(node.right)
res.append(node.val)
dfs(root)
return res
总结:
按照上面讲的遍历二叉树的三部曲:
1. 确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
2. 确定终止条件:写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
3. 确定单层递归的逻辑:确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。(前序、中序、后序,是不同的,要分清)
把逻辑理清楚,就不难。