二叉树的基本层次遍历
二叉树最简单的情况,仅仅遍历输出全部元素
3
/ \
9 20
/ \
15 7
上面的二叉树层次遍历结果输出为[3, 9, 20, 15, 7 ]
如 LeetCode102这道题
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
基本思想是:
从根节点开始,一层一层的访问,先访问3,然后访问3的左右孩子9和20,接着访问9的左右孩子,再访问20的左右孩子15,7
算法基本思想是:
- 首先 3 入队
- 然后取队头元素(这里也就是3),然后该节点出队,接着将其左右孩子入队
- 循环步骤 2,直到队列中的元素全是叶子结点,随后全部出队
代码如下:
vector<vector<int>> levelOrder(TreeNode* root) {
// 定义一个二维数组用来存储每一层的元素
vector<vector<int>> ret;
// 判空
if(!root) {
return ret;
}
// 初始化队列
queue<TreeNode*> q;
// 根节点入队
q.push(root);
// 循环步骤2
while(!q.empty()) {
// 先获取当前队列的大小,保证每次只遍历当前层次
int nsize = q.size();
// 当前层遍历完后,将当前层的结果数组添加到ret的末尾
ret.push_back(vector<int>());
// 遍历当前层
for(int i = 0; i < nsize; i++) {
// 取队头
auto node = q.front();
q.pop();
// cout << node->val << ' ';
// 遍历当前层,每取出一个节点就把当前节点的值添加到数组末尾
ret.back().push_back(node->val);
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
}
return ret;
}
接下来看一道这道题的变体:
LeetCode 107
给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[15,7],[9,20],[3]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
这道题要求自底向上的层序遍历,无非就最后返回的时候把这个二维数组翻转一下就行了,调用库函数reverse(it1, it2),需要了解的是两个参数都是迭代器,即iterator,而vector的begin()和end()正是起止迭代器
vector<vector<int>> levelOrderBottom(TreeNode* root) {
vector<vector<int>> ret;
if(!root) {
return ret;
}
queue<TreeNode*> q;
q.push(root);
while(!q.empty()) {
int nsize = q.size();
ret.push_back(vector<int>());
for(int i = 0; i < nsize; i++) {
auto node = q.front();
q.pop();
ret.back().push_back(node->val);
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
}
reverse(ret.begin(), ret.end());
return ret;
}
再来一道变体:
LeetCode 199
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例 1:
输入: [1,2,3,null,5,null,4]
输出: [1,3,4]
示例 2:
输入: [1,null,3]
输出: [1,3]
示例 3:
输入: []
输出: []
这道变体只需要输出每一层的最后一个结点元素,也就是在第一道题的基础上,把二维数组的每一行的最后一个元素输出出来就行了,我们可以把他们取出来存在一维数组中
vector<int> rightSideView(TreeNode* root) {
vector<vector<int>> ret;
if(!root) {
return vector<int>();
}
queue<TreeNode*> q;
q.push(root);
vector<int> ans;
while(!q.empty()) {
int nsize = q.size();
ret.push_back(vector<int>());
for(int i = 0; i < nsize; i++) {
auto node = q.front();
q.pop();
ret.back().push_back(node->val);
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
// 取每一行最后一个元素
if(i == nsize - 1) {
ans.push_back(ret.back().back());
}
}
}
return ans;
}
本文讲解了如何通过队列实现二叉树的层序遍历,包括常规遍历、自底向上遍历以及右侧视图,适合学习数据结构和算法基础。
608

被折叠的 条评论
为什么被折叠?



