二叉树中除了前序、中序、后序遍历外,还有一种 从上到下、从左到右的层次遍历方法。这种方法更符合人视觉的直观感受,在计算树的最大深度、返回最外层叶节点、返回二叉树的列表表示等场景有着优秀的性能。
列表表示法是二叉树图示方法外最为重要的表示方法,可以通过层次遍历实现。
一、创建二叉树
参考二叉树的创建,构建一个二叉树:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
node4 = TreeNode(1)
node5 = TreeNode(4)
node6 = TreeNode(6)
node7 = TreeNode(9)
node2 = TreeNode(3, node4, node5)
node3 = TreeNode(7, node6, node7)
node1 = TreeNode(5, node2, node3)
root = node1
二、层次遍历
2.1 代码详解
- 如果 root 节点为空,则返回空列表。
- Level、Next 分别记录当前层节点和下一层节点。
- Vals、Res 分别记录当前层的值和所有层的值。Res 是 Vals 的累加。
- 循环当前节点 Level,可以获得当前层的值 Vals 和下一层的节点 Next 。
- 当 Next 为空时,结束遍历,退出 while 循环,返回 Res 二维数组。
def levelTraversal(root):
if not root:
return []
Level = [root] # 当前遍历层
Res = [] # 层次遍历返回结果
while True:
Vals = [] # 当前层节点的值
Next = [] # 下一层的节点
for node in Level:
Vals.append(node.val)
if node.left is not None: # 若存在左子节点,计入到下一层
Next.append(node.left)
if node.right is not None: # 若存在右子节点,计入到下一层
Next.append(node.right)
Res.append(Vals)
if len(Next) == 0: # 如果下一层没有节点,说明遍历完成
break
else:
Level = Next
return Res
运行函数,返回二维列表表达式:
>>> print(levelTraversal(root))
>>> [[5], [3, 7], [1, 4, 6, 9]]
二维列表表达式虽然可以用于遍历,但只能单向地表示二叉树,并不能还原二叉树的结构,因而在第三部分需要使用别的方式来表示。
2.2 简洁写法
def levelTraversal(root):
if not root:
return []
Level, Res = [root], []
while Level:
Vals, Next = [], []
for node in Level:
Vals.append(node.val)
if node.left:
Next.append(node.left)
if node.right:
Next.append(node.right)
Res.append(Vals)
Level = Next
return Res
三、列表表示法
列表表达式跟二叉树是一一对应的,是二叉树最常见的表达方式之一,二者可以互相转换。
3.1 规则说明
从上到下、从左到右遍历时:
- 如果父节点只有一个子节点,在缺少的左/右子节点位置使用 “null” 替代。
- 如果是最后一层的叶节点,缺少左右子节点,此时子节点 全为 “null”,因而可以省略简写。
如上图:
- 第一层为根节点,所以列表表达式开头为 [7];
- 第二层为满层,所以本层的列表表达式为 [3,9];
- 第三层中,9 的左右子节点都为空,用“null”填充,本层的表达式为 [1,4,null,null];
- 第四层中,1 的子节点和 4 的左子节点为空,用“null”填充,本层的表达式为 [null,null,null,5];
- 第五层中,5 的左子节点为空,用“null”填充,本层的表达式为 [null,6];
- 此时,已经到达最后一层,不需要再填充了,将以上各层直接串联,即可得到最终的表达式:
[7,3,9,1,4,null,null,null,null,null,5,null,6]
3.2 代码实现
'''
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
node7 = TreeNode(6)
node6 = TreeNode(5, None, node7)
node5 = TreeNode(4, None, node6)
node4 = TreeNode(1)
node3 = TreeNode(9)
node2 = TreeNode(3, node4, node5)
node1 = TreeNode(7, node2, node3)
root = node1
'''
def listExpress(root):
if not root:
return []
Level = [root]
Expre = [root.val]
while True:
Next = []
for node in Level:
if node.left:
Expre.append(node.left.val)
Next.append(node.left)
else:
Expre.append("null")
if node.right:
Expre.append(node.right.val)
Next.append(node.right)
else:
Expre.append("null")
if not Next:
return Expre[:len(Expre) - len(Level) * 2]
Level = Next
函数调用:
>>> print(listExpress(root))
>>> [7, 3, 9, 1, 4, 'null', 'null', 'null', 'null', 'null', 5, 'null', 6]