二叉树的层序遍历过程和广度优先搜索 BFS 的搜索过程非常相像,因此考虑用 BFS 算法进行解题。
深度优先算法(DFS )利用的数据结构是栈,这个栈是系统自己维护的;
广度优先算法(BFS)利用的数据结构是队列,这个队列需要我们自己手动维护。
1. 二叉树的层序遍历(102)
这道题目不仅要求对二叉树进行层序遍历,还要求将得到的结点值分层存储,每一层放在一个小数组里,最后用一个大数组将所有小数组存起来。因此还需要构造两个数组来存储结果。
知识点: queue 容器的使用(元素的插入、删除、取最前端元素、队列的大小,队列是否为空),BFS
1.1 队列实现 BFS
这里先给出使用队列实现 BFS 的代码。
- 判断二叉树是否为空,如果非空就将根节点加入到队列中
- 判断队列是否为空,如果非空就将队列最前端的结点 node 弹出,并将 node 的左右子节点放入队列中。
- 重复 2 ,直至队列为空。
void bfs(TreeNode* root) {
TreeNode* node;
queue<TreeNode*> q;
if(!root)
q.push(root);
while(!q.empty())
{
node = q.front();
q.pop();
if(node->left != nullptr)
q.push(node->left);
if(node->right != nullptr)
q.push(node->right);
}
}
1.2 层序遍历
用队列实现 BFS 会将所有结点放入一个队列中,无法区分结点来自哪一层。要想实现层序遍历,就需要 “在每一层遍历开始前,先记录队列中的结点数量 n(也就是这一层的结点数量),然后一口气处理完这一层的 n 个结点。”
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
queue<TreeNode*> q;
if(root != nullptr)
{
q.push(root);
}
while(!q.empty())
{
# 注意 temp 数组需在循环内部创建,实现初始化
vector<int> temp;
int n = q.size();
while(n--)
{
TreeNode* node = q.front();
temp.push_back(node->val);
q.pop();
if(node->left != nullptr)
q.push(node->left);
if(node->right != nullptr)
q.push(node->right);
}
result.push_back(temp);
}
return result;
}
};
2. 二叉树的层序遍历 II (107)
本题和 102 题几乎完全相同,不同的地方在于返回的是自底向上的层序遍历,是 102 题结果的倒序。因此利用 reverse 直接将 102 题得到的数组倒序反转即可。
知识点: vector 容器的使用(reverse 反转)
具体代码实现如下:
class Solution {
public:
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> result;
queue<TreeNode*> q;
if(root != nullptr)
q.push(root);
while(!q.empty())
{
int n = q.size();
vector<int> temp;
while(n--)
{
TreeNode* node = q.front();
temp.push_back(node->val);
q.pop();
if(node->left != nullptr)
{
q.push(node->left);
}
if(node->right != nullptr)
{
q.push(node->right);
}
}
result.push_back(temp);
}
reverse(result.begin(), result.end());
return result;
}
};