1. 前言
在做二叉树相关的算法题时,常常会遇到二叉树的遍历问题。而二叉树的遍历有4种方式,本文仅记录这4种遍历方式的递归实现和迭代实现。
2. 深度优先遍历(DFS)
DFS有三种,前序遍历
,中序遍历
和后序遍历
。这3种遍历方式是基于根节点的先后而言的。
2.1 前序遍历
以根-左-右
的顺序遍历二叉树中的节点。遍历顺序为:A-B-D-E-C-F-G
特点是,第一个节点为二叉树的根节点,子树也满足此规律。
- 根节点A加入栈中,栈为 [A];
- 从栈中弹出节点A,将节点A的右子节点C和左子节点B依次入栈,此时栈为 [C, B];
- 从栈中弹出节点B,将节点B的右子节点E和左子节点D依次入栈,此时栈为 [C, E, D];
- 从栈中弹出节点D,没有左子节点,此时栈为 [C, E];
- 继续上述步骤。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def pre_order(self, root):
"""
递归实现
"""
if not root: return
print(root.val)
self.pre_order(self, root.left)
self.pre_order(self, root.right)
def pre_order(self, root):
"""
迭代实现,推荐使用
"""
if not root: return []
result = []
stack = [root]
while stack:
node = stack.pop()
result.append(node.val)
# 先加入右,再加左,因为LIFO
if node.right: stack.append(node.right)
if node.left: stack.append(node.left)
return result
2.2 中序遍历
以左-根-右
的顺序遍历二叉树中的节点。遍历顺序为:D-B-E-A-F-C-G
特点是,根节点左边的节点都在左子树,根节点右边的节点都在右子树,子树也满足此规律。
- 有左就往左走,直到当前节点的最左子节点;
- 有右就往右走1步,再重复第1步,否则回溯到父节点,再重复第1步;
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def in_order(self, root):
"""
递归实现
"""
if not root: return
self.in_order(self, root.left)
print(root.val)
self.in_order(self, root.right)
def in_order(self, root):
"""
迭代实现
"""
result = []
stack = []
while root or stack:
# 1. 有左就往左走,直到最左子节点
while root:
stack.append(root)
root = root.left
# 2. 有右就往向右走1步,在重复第1步
root = stack.pop()
result.append(root.val)
root = root.right
return result
2.3 后序遍历
以左-右-根
的顺序遍历二叉树中的节点。遍历顺序为:D-E-B-F-G-C-A
特点是,最后一个节点为根节点,子树也满足此规律。
因为先序遍历的顺序是 根-左-右, 后序遍历的顺序是 左-右-根。
采用先序遍历的变形,首先实现一个根-右-左的遍历,然后将其压入辅助栈中,最后依次将辅助栈中的元素弹出即可。
例子中,根-右-左的遍历顺序为:A-C-G-F-B-E-D
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def last_order(self, root):
"""
递归实现
"""
if not root: return
self.last_order(self, root.left)
self.last_order(self, root.right)
print(root.val)
def last_order(self, root):
"""
迭代实现
"""
if not root: return []
result = []
stack = [root]
while stack:
node = stack.pop()
result.append(node.val)
# 先入左,再入右
if node.left: stack.append(node.left)
if node.right: stack.append(node.right)
result.reverse() # 逆序,将根-右-左变换为左-右-根
return result
3. 广度优先遍历(BFS)
广度优先遍历也就是我们常说的层序遍历
。遍历顺序为:A-B-C-D-E-F-G
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def bfs(self, root):
"""
迭代实现版本1
层序遍历
"""
if not root: return
result = []
queue = [root]
while queue:
node = queue.pop(0)
result.append(node.val)
if node.left: queue.append(node.left)
if node.right: queue.append(node.right)
return result
def bfs(self, root):
"""
迭代实现版本2。这两者的区别是,版本2能够获取具体每一层的数据,而版本1的混在一起的。
层序遍历
"""
if not root: return
result = []
queue = [root]
while queue:
next_level = [] # 记录下一层的节点
while queue:
node = queue.pop(0)
result.append(node.val)
if node.left: next_level.append(node.left)
if node.right: next_level.append(node.right)
queue = next_level
return result
总结
本文仅是记录二叉树的实现,免得忘了之后又得在网上找半天。