【python】二叉树的 层次遍历 & 列表表示法


  二叉树中除了前序、中序、后序遍历外,还有一种 从上到下、从左到右的层次遍历方法。这种方法更符合人视觉的直观感受,在计算树的最大深度、返回最外层叶节点、返回二叉树的列表表示等场景有着优秀的性能。
   列表表示法是二叉树图示方法外最为重要的表示方法,可以通过层次遍历实现。

一、创建二叉树

参考二叉树的创建,构建一个二叉树:

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]

猜你喜欢

转载自blog.csdn.net/weixin_44844635/article/details/131641514