102.二叉树的层序遍历
107.二叉树的层次遍历II
199.二叉树的右视图
637.二叉树的层平均值
429.N叉树的层序遍历
515.在每个树行中找最大值
116.填充每个节点的下一个右侧节点指针
117.填充每个节点的下一个右侧节点指针II
104.二叉树的最大深度
111.二叉树的最小深度
以 102 题 为例子;
1. 广度优先遍历的 迭代实现
1.1 广度优先 与 深度优先, 两个迭代法的区别
区别于
深度优先遍历中:
存储访问的节点 使用的是栈,
由于 栈的 先入后出 特性, 从而导致了 在 深度优先遍历中,
树节点的入栈 顺序 和 结果集中保存的节点数值 顺序, 总是相反的;
而在 广度优先遍历中:
存储访问的节点 是一个队列, 并且是一个 双端队列, 方便直接从队首 取出元素;
从而 节点的 入队 顺序与 ,节点的数值保存到结果集中是一致的;
并且, 层序遍历中, 访问 当前节点, 与处理当前该节点中数值 正好可以做到同步;
1.2 算法步骤
层序遍历迭代法中关键思想:
初始化一个新队列1
遍历队列时, 在每次遍历到 一个新的层时:
新建一个空的队列2, 用于存放当前层节点的 左右孩子节点;
将队列1 更新为队列2, 队列1 = 队列2
算法步骤:
def levelOrderTraversal(root: TreeNode)-> list:
if root == None:
return []
results = []
que = [root] # 根节点不为空, 将根节点入队;
while que: # 循环, 队列中还有节点时
results.append([ cur_Node.val for cur_Node in que ])
cur_level_child_node = [] # 用于存储当前层的孩子节点列表
for cur_Node in que:
if cur_Node.left != None:
cur_level_child_node.append(cur_Node.left)
if cur_Node.right != None:
cur_level_child_node.append(cur_Node.right)
que = cur_level_child_node
return results
------方法 2--------------------------
import collections
def levelOrderTraversal(root: TreeNode)-> list:
results = []
if root == None:
return results
que = collections.deque([root]) # 根节点不为空, 将根节点入队;
while que: # 大循环, 队列中 还有节点时
len_que = len(que)
result = []
for _ in range(len_que): # 更新队列为当前层的子节点队列;
cur_Node = que.popleft()
result.append(cur_Node.val)
if cur_Node.left != None:
que.append(cur_Node.left)
if cur_Node.right != None:
que.append(cur_Node.right)
results.append(result)
return results
2. 广度优先遍历的 递归实现
回顾一下递归三要素
- 递归函数的输入参数, 输出参数;
- 递归的 终止条件;
- 单层递归执行的步骤
注意 层序遍历的 递归遍历,
只要是 递归, 其本质 仍然是与 栈的实现有关,
这里体现在,
层序遍历时, 访问过的元素, 会被第二次访问,
故遍历的时候
在遍历到最底层的时候,
便会沿着之前遍历过的节点返回;
18 -> 7 -> 3 -> 7 -> 4 -> 7 -> 18 -> 11
如图中的 节点7 ,
被访问 三次, 第一次节点18 到 节点7,
第二次,节点 3 到节点7;
第三次, 节点4 到节点7
当结果集中, 列表的个数 == 层数时,
说明该节点 属于 传入的 第 depth 层中;
将其压入结果集中的 第 (depth -1) 个列表中;
2.1 算法步骤
- 创建结果集
- 递归函数
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
def level(root: TreeNode, depth, result):
if root == None:
return []
if len(result) < depth: # 如果当前结果集中, 非空列表的个数 < 当前的 层数时;
result.append([])
# 将当前节点的数值存放到它所在树中的层数,该层数 对应到 结果集中的 第(depth -1) 个列表;
result[depth - 1].append(root.val)
if root.left != None: # 如果该节点的左子树节点不为空,将该节点递归到保存到它所应该在的层数中;
level(root.left, depth + 1, result)
if root.right != None:
level(root.right, depth + 1, result)
result = [] # 结果集中,空列表,
level(root, 1, result) # 根节点 是从层数 1 开始的;
return result