本文简单介绍一下二叉树的遍历以及二叉树的相关题目。
1. 二叉树的遍历
1.1 前序遍历
根节点->左子树->右子树
1 | #递归实现 |
1.2 中序遍历
左子树->根节点->右子树
1 | # 递归不带返回值 |
1.3 后序遍历
左子树->右子树->根节点
1 | def traversal(node, result): |
1.4 非递归实现二叉搜索数的遍历
非递归就是栈的实现,用栈来模拟递归调用, 参考文档https://juejin.cn/post/6844903503807119374
- 先序遍历
不需要入栈,每次遍历到“左”节点,立即输出即可。
需要注意的是,遍历到最左下的节点时,实际上输出的已经不再是实际的根节点,而是实际的左节点。这符合先序的定义。
1 | def preorderTraversal(node): |
- 中序遍历
基于对先序的分析,先序与中序的区别只在于对“左”节点的处理上,我们调整一行代码即可完成中序遍历。注意,我们在出栈之后才访问这个节点。因为先序先访问实际根,后访问实际左,而中序恰好相反。相同的是,访问完根+左子树(先序)或左子树+根(中序)后,都需要转向到“右”节点,使“右”节点称为新的“左”节点。1
2
3
4
5
6
7
8
9
10
11
12
13def inorderTraversal(node):
res, stack = [], []
if not root: return res
cur = root
while stack or cur:
while cur:
stack.append(cur)
cur = cur.left
top = stack.pop()
res.append(top.val)
cur = top.left - 后序遍历
后序遍历是左右中,按照中右左入栈,然后逆序就可以。方法二:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15def postorderTraversal(node):
res, stack = [], []
if not root: return res
cur = root
while stack or cur:
while cur:
res.append(cur.val)
stack.append(cur)
cur = cur.right
top = stack.pop()
cur = top.left
return res[::-1]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22def postorderTraversal(self, root):
res, stack = [], []
if not root: return res
cur = root
prev = None
while cur or stack:
while cur:
stack.append(cur)
cur = cur.left
top = stack.pop()
if not top.right or top.right == prev:
res.append(top.val)
prev = top
cur = None
else:
stack.append(top)
cur = top.right
return res2.运用递归解决树的问题
递归分为”自底向上”,”自顶向下”的递归
2.1 自顶向下的递归
自顶向下的递归,就是记录经过的path,继续执行下一个step,下面是一个自顶向下求解二叉树深度的例子
1 | def max_depth(node, depth): |
2.2 自底向上的递归
自底向上是带返回值的递归
1 | def max_depth(node): |
3. 二叉树相关题
3.1 最近公共祖先
1 | """ |
3.2 二叉树root到叶子节点的最大和
1 | def maxPath(root): |
3.3 二叉树root到任意节点的最大和
1 | def maxPath(root): |
3.4 二叉树任意节点到任意节点的最大和
两个分治
首先讨论情况,主要分三种,
- 垮root节点路径在root的两边
该类问题结果就是 max(root.left to any的最大值, 0) + max(root.right to any 的最大值, 0 )+ root.val - 路径全在左子树: 递归调用即可
- 路径全在由子树: 递归调用即可
1 | def maxPathAny2Any(node): |