赞
踩
在刷 leetcode 二叉树相关的题目时,经常有这样给定的例子,例如: 检查平衡性
实现一个函数,检查二叉树是否平衡。在这个问题中,平衡树的定义如下:任意一个节点,其两棵子树的高度差不超过 1。 示例 1: 给定二叉树 [3,9,20,null,null,15,7] 3 / \ 9 20 / \ 15 7 返回 true 。 示例 2: 给定二叉树 [1,2,2,3,3,null,null,4,4] 1 / \ 2 2 / \ 3 3 / \ 4 4 返回 false 。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/check-balance-lcci 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
如果我们想要在本地调试程序,就需要生成相应的二叉树,进而调试代码。然而,每次如果要手动添加 Node 来生成树是非常麻烦的。
根据示例,给我们的是一个分层顺序列表 类似于 [3,9,20,null,null,15,7]
。我们可以非常直观的知道 3 是根结点, 9 和 20 是 3 的左右子节点, null 和 null 是 9 的左右子节点,15 和 7 是 20 的左右子节点。
从上面的描述中,可以发现分配左右节点的先后顺序也是 3,9,20,跟列表顺序是一致的,即先给 3 分配左右节点,再给 9 分配左右节点,再给 20 分配左右节点,如果列表更长,接下来会跳过null,给 15 分配左右节点,再给 7 分配左右节点。
因此,我们可以用队列来实现二叉树的初始化中这种先入先出的特点。下面的图示说明了队列初始化二叉树的过程:
# 节点类 class Node(object): def __init__(self, x): self.val = x self.left = None self.right = None # 树生成代码 def generate_tree(vals): if len(vals) == 0: return None que = [] # 定义队列 fill_left = True # 由于无法通过是否为 None 来判断该节点的左儿子是否可以填充,用一个记号判断是否需要填充左节点 for val in vals: node = Node(val) if val is not None else None # 非空值返回节点类,否则返回 None if len(que)==0: root = node # 队列为空的话,用 root 记录根结点,用来返回 que.append(node) elif fill_left: que[0].left = node fill_left = False # 填充过左儿子后,改变记号状态 if node: # 非 None 值才进入队列 que.append(node) else: que[0].right = node if node: que.append(node) que.pop(0) # 填充完右儿子,弹出节点 fill_left = True # return root # 定义一个dfs打印中序遍历 def dfs(node): if node is not None: dfs(node.left) print(node.val, end=' ') dfs(node.right) # 定义一个bfs打印层序遍历 def bfs(node): que = [] que.append(node) while que: l = len(que) for _ in range(l): tmp = que.pop(0) print(tmp.val, end=' ') if tmp.left: que.append(tmp.left) if tmp.right: que.append(tmp.right) print('|', end=' ') # test null = None vals = [3,9,20,null,null,15,7] tree = generate_tree(vals) print('中序遍历:') dfs(tree) # 9 3 15 20 7 print('\n层序遍历:') bfs(tree) # 3 | 9 20 | 15 7 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。