题目本文稍后补全,以下内容来自:https://blog.csdn.net/weixin_60702024/article/details/141615340
给定二叉树的根节点root,写出函数实现对二叉树的层次遍历。
分析实现
二叉树的层次遍历的访问顺序,可以非常直观地看出。但二叉树本身的存储结构并不能直接实现层次遍历,常见的遍历方式是借助队列存储当前层的所有结点,思路如下:
- 将根节点
root
加入队列q
- 对于队列中每个结点
cur
,访问队首结点cur
,将cur
出队,再将cur
的子节点加入q
- 重复2直到
q
为空
具体实现如下:
#include <queue>
// 队列实现层次遍历
void levelOrder(BTNode* root) {
if (root == NULL)
return;
queue<BTNode*> q;
q.push(root);
while (!q.empty()) {
BTNode* cur = q.front();
q.pop();
// 访问当前结点 e.g: cout<<cur->val<<' ';
visit(cur);
if (cur->left != NULL)
q.push(cur->left);
if (cur->right != NULL)
q.push(cur->right);
}
}
这是常见的层次遍历写法,在此基础之上,还可以进行一点改进使得遍历过程更加灵活:
- 将根节点
root
加入队列q
- 记录当前
q
的元素个数n
,执行n
次 “访问cur
,出队cur
,加入cur
子节点” - 重复2直到
q
为空
此处最大的改动在于(2),改动前每一步(2)只会执行1次 “访问cur
,出队cur
,加入cur
子节点”,改动后每一步(2)会直接执行n次 “访问cur
,出队cur
,加入cur
子节点” ,这样每次执行(2)都固定对一层的结点进行操作并出队。
通过这种改进,可以很简单地分清每一层结点,使用实例如下:
// 分层输出的层次遍历
void levelOrder(BTNode* root) {
if (root == NULL)
return;
queue<BTNode*> q;
q.push(root);
// 定义变量记录当前层次
int layer = 1;
while (!q.empty()) {
cout << "当前访问的层次为:" << layer << endl;
layer++;
// 定义变量记录当前层次结点个数
int n = q.size();
while (n--) {
BTNode* cur = q.front();
q.pop();
cout << cur->val << " ";
if (cur->left != NULL)
q.push(cur->left);
if (cur->right != NULL)
q.push(cur->right);
}
cout << endl; // 换行以区分不同层次的节点
}
}
总结
以上就是常用的使用队列实现层次遍历的实现,已经十分常用的小改进。
代码中使用了c++的<queue>
头文件,queue
的常用操作如下:
queue<int> q; // 定义一个存储int型元素的队列q
q.empty(); // return bool, 若q为空,返回true
q.size(); // return size_t, 返回q中元素个数,不会溢出的情况下经常存储于int变量中
q.push(x); // 将元素x添加到队列尾部
q.pop(); // 将队首元素出队
q.front(); // 返回队首元素
q.back(); // 返回队尾元素