题目:
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
解题思路:
I. 按层打印: 题目要求的二叉树的 从上至下 打印(即按层打印),又称为二叉树的 广度优先搜索(BFS)。BFS 通常借助 队列 的先入先出特性来实现。
II. 每层打印到一行: 将本层全部节点打印到一行,并将下一层全部节点加入队列,以此类推,即可分为多行打印。
算法流程:
- 特例处理: 当根节点为空,则返回空列表 [] 。
- 初始化: 打印结果列表 res = [] ,包含根节点的队列 queue = [root] 。
- BFS 循环: 当队列 queue 为空时跳出。
a. 新建一个临时列表 tmp ,用于存储当前层打印结果。
b. 当前层打印循环: 循环次数为当前层节点数(即队列 queue 长度)。
1) 出队: 队首元素出队,记为 node。
2)打印: 将 node.val 添加至 tmp 尾部。
3)添加子节点: 若 node 的左(右)子节点不为空,则将左(右)子节点加入队列 queue 。
c. 将当前层结果 tmp 添加入 res 。 - 返回值: 返回打印结果列表 res 即可。
C++:
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode()
{
left = right = nullptr;
}
TreeNode(int x)
{
val = x;
left = right = nullptr;
}
TreeNode(int x, TreeNode *left, TreeNode *right)
{
val = x;
left = left; right = right;
}
};
class Solution
{
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
queue<TreeNode*> que; // 队列:用于存储下一层的节点,类型为链表中的节点,故为<TreeNode*>
vector<vector<int>> res; // 存储结果的vector
if (root != nullptr) que.push(root);
while (! que.empty()) // 队列que为空时跳出
{
vector<int> tmp; // 临时列表,用于存储当前层的打印结果
for (int i = que.size(); i > 0; i--) // 当前层的打印循环
{
root = que.front(); // 取队首节点
que.pop(); // 删除队首节点
tmp.push_back(root->val); // 队首节点元素添加至tmp中
// 添加下一层的子节点至que,用于下一步计算
if (root->left != nullptr) que.push(root->left);
if (root->right != nullptr) que.push(root->right);
}
// 当前层结果 tmp 添加至res
res.push_back(tmp);
}
return res;
}
};
python:
Python 中使用 collections 中的双端队列 deque()
pop() 和 popleft() 是 Python 标准库 collections 模块中 deque(双端队列)对象的方法,用于从队列中删除元素。
pop() 方法用于从队列的右侧(末尾)删除元素,并返回被删除的元素。
popleft() 方法用于从队列的左侧(开头)删除元素,并返回被删除的元素。
import collections
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def levelOrder(self, root):
if not root: return []
res, queue = [], collections.deque()
queue.append(root)
while queue:
tmp = []
for _ in range(len(queue)):
node = queue.popleft()
tmp.append(node.val)
if node.left: queue.append(node.left)
if node.right: queue.append(node.right)
res.append(tmp)
return res