题目描述
给你二叉树的根节点 root ,返回其节点值的 层序遍历。(即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
思路
队列是一种先进先出(FIFO)的数据结构,非常适合于层序遍历,因为我们总是希望按照从树的上层到下层的顺序处理节点。
1、初始化阶段
- 首先,检查传入的根节点是否为null。如果不为null,则将根节点加入到队列中。这个步骤是层序遍历的启动点,确保了从树的根节点开始遍历。
2、遍历阶段
队列操作:使用一个队列来管理待处理的树节点。队列的先进先出特性保证了树的每一层都按照从左到右的顺序被处理。
层级处理:
- 循环开始时,首先检查队列是否为空。只要队列中还有节点,就继续遍历。
- 对于每一层,首先获取队列的当前大小,这个大小表示该层的节点数量。
- 初始化一个向量vec,用于存储当前层所有节点的值。
节点处理:
- 对当前层中的每个节点进行循环处理。循环中,每次从队列中取出队列前端的节点(当前节点),并从队列中移除它。
- 将当前节点的值加入到当前层的向量vec中。
- 检查当前节点是否有左子节点和右子节点。如果有,将这些子节点按顺序加入到队列中,以便在后续的层次中遍历它们。
存储层次数据:
- 完成当前层的节点处理后,将当前层的向量vec添加到最终结果的向量result中。这样,result逐步构建成一个包含所有层次数据的二维向量。
3、结束阶段
- 当队列为空时,循环结束,此时所有树节点都已按层序遍历完毕。
- 函数返回最终的二维向量result,这个向量现在包含了树的层序遍历结果,其中每个内部向量代表树的一层。
4、总体来看
- 时间复杂度:每个节点恰好被访问一次,因此时间复杂度为O(n),其中n是树中的节点总数。
- 空间复杂度:在最坏的情况下(完全二叉树),队列可能需要存储大约n/2个节点(最后一层的节点),因此空间复杂度也是O(n)。
完整代码
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) { // 接受一个 TreeNode* 类型的参数,返回一个 vector<vector<int>> 类型的二维向量。
queue<TreeNode*> que; // 用于按层序存储树中的节点,以便按顺序访问
if(root != NULL) que.push(root);
vector<vector<int>> result;
while(!que.empty()){
int size = que.size();
vector<int> vec;
for(int i = 0; i < size; i++){
TreeNode* node = que.front();
que.pop();
vec.push_back(node->val);
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
result.push_back(vec);
}
return result;
}
};
int main() {
// 创建特定的二叉树:[3,9,20,null,null,15,7]
TreeNode* root = new TreeNode(3);
root->left = new TreeNode(9);
root->right = new TreeNode(20);
root->right->left = new TreeNode(15);
root->right->right = new TreeNode(7);
Solution solution;
vector<vector<int>> result = solution.levelOrder(root);
for (const vector<int>& level : result) {
for (int val : level) {
cout << val << " ";
}
cout << endl;
}
return 0;
}