目录
理论基础
递归遍历
144. 二叉树的前序遍历
94. 二叉树的中序遍历
145. 二叉树的后序遍历
迭代遍历
前序遍历
后序遍历
中序遍历
统一遍历
代码随想录 (programmercarl.com)
二叉树主要有两种遍历方式:
这两种遍历是图论中最基本的两种遍历方式,后面在介绍图论的时候 还会介绍到。
那么从深度优先遍历和广度优先遍历进一步拓展,才有如下遍历方式:
在深度优先遍历中:有三个顺序,前中后序遍历, 有同学总分不清这三个顺序,经常搞混,我这里教大家一个技巧。
这里前中后,其实指的就是中间节点的遍历顺序,只要大家记住 前中后序指的就是中间节点的位置就可以了。
看如下中间节点的顺序,就可以发现,中间节点的顺序就是所谓的遍历方式
图解 二叉树的四种遍历 - 二叉树的前序遍历 - 力扣(LeetCode)
由于层次遍历的递归解法不是主流,因此只介绍前三种的递归解法。它们的模板相对比较固定,一般都会新增一个 dfs 函数
对于前序、中序和后序遍历,只需将递归函数里的 res.append(root.val)
放在 不同位置 即可,然后调用这个递归函数就可以了,代码完全一样。
# 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: Optional[TreeNode]) -> List[int]:
res = []
def dfs(root):
if not root:
return []
res.append(root.val) # 将根节点值加入结果
dfs(root.left) # 左
dfs(root.right) # 右
dfs(root)
return res
# 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: Optional[TreeNode]) -> List[int]:
res = []
def dfs(root):
if not root:
return []
dfs(root.left) # 左
res.append(root.val) # 将根节点值加入结果
dfs(root.right) # 右
dfs(root)
return res
# 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: Optional[TreeNode]) -> List[int]:
res = []
def dfs(root):
if not root:
return []
dfs(root.left) # 左
dfs(root.right) # 右
res.append(root.val) # 将根节点值加入结果
dfs(root)
return res
前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。
为什么要先加入 右孩子,再加入左孩子呢? 因为这样出栈的时候才是中左右的顺序。
# 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: Optional[TreeNode]) -> List[int]:
if not root:
return []
stack, res = [root], []
while stack:
node = stack.pop()
if node:
res.append(node.val) # 根节点加入到结果中
if node.right: # 右子树入栈
stack.append(node.right)
if node.left: # 左子树入栈
stack.append(node.left)
return res
在前序遍历的基础上,将左右的顺序调整一下变成中右左,最后在将数组翻转就变成了左右中。
# 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]:
if not root:
return []
stack, res = [root], []
while stack:
node = stack.pop()
if node:
res.append(node.val) # 根节点加入到结果中
if node.left: # 左子树入栈
stack.append(node.left)
if node.right: # 右子树入栈
stack.append(node.right)
return res[::-1]
先把根节点和所有的左孩子放到栈中,当cur为空时,开始弹出元素放入res中,弹出元素后,取他的右孩子当做cur放到栈中。知道栈为空结束循环
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
stack = [] # 不能提前将root结点加入stack中
result = []
cur = root
while cur or stack:
# 先迭代访问最底层的左子树结点
if cur:
stack.append(cur)
cur = cur.left
# 到达最左结点后处理栈顶结点
else:
cur = stack.pop()
result.append(cur.val)
# 取栈顶元素右结点
cur = cur.right
return result