层序遍历,是按照层数从低到高,同一层从左到右遍历。在这里采用递归法是无法做到的,观察遍历的特点,这里需再加一个队列来实现。
天津网站制作公司哪家好,找创新互联!从网页设计、网站建设、微信开发、APP开发、自适应网站建设等网站项目制作,到程序开发,运营维护。创新互联公司2013年成立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联。在将一层一层的二叉树节点放入队列以及弹出队列的操作中,需要记录和知道弹出的个数size。
具体思路和步骤如代码:
102.二叉树的层序遍历 #力扣题目链接class Solution {
public:
vector>levelOrder(TreeNode* root) {
queueque;
vector>result;
if(root != NULL) que.push(root); //弹入根节点
while(!que.empty()){
int size = que.size(); //记录size个数
vectorvec; //记录某一层的结果
while(size--){
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;
}
};
107.二叉树的层序遍历②#力扣题目链接在102的基础上进行结果翻转即可。
reverse(result.begin(), result.end());
199.二叉树的右视图#力扣题目链接这道题的核心思想:就是将每一层弹出的最后一个放入结果数组中,就可以了。
class Solution {
public:
vectorrightSideView(TreeNode* root) {
queueque;
vectorresult;
if(root != NULL) que.push(root); //弹入根节点
while(!que.empty()){
int size = que.size(); //记录size个数
while(size--){
TreeNode* node = que.front(); //获取要弹出的节点
que.pop(); //队列弹出
if(size == 0){
result.push_back(node->val); //最后一个弹出的放入结果数组即可
}
if(node->left) que.push(node->left); //获取这个节点的左孩子
if(node->right) que.push(node->right); //获取这个节点的右孩子
}
}
return result;
}
};
637.二叉树的层平均值 #力扣题目链接这一道题的思路:在每一层的元素弹出时,记录下来并进行加和,在每一层弹出结束后将再将平均数放到result数组中即可。
class Solution {
public:
vectoraverageOfLevels(TreeNode* root) {
double sum = 0; //记录求和
vectorresult;
queueque;
if(root != NULL) que.push(root);
while(!que.empty()){
int size = que.size();
double count = 0; //记录某一层的元素个数
double sum = 0; //记录所有数的加和
while(size--){
TreeNode* node = que.front();
que.pop();
count++;
sum += node->val;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
result.push_back(sum / count); //将每一层的平均数放到数组里
}
return result;
}
};
429.N叉树的层序遍历#力扣题目链接n叉树和二叉树的层序遍历区别不大,这里将left、right变换成children[i]就可以了。
class Solution {
public:
vector>levelOrder(Node* root) {
queueque;
vector>result;
if(root != NULL) que.push(root); //弹入根节点
while(!que.empty()){
int size = que.size(); //记录size个数
vectorvec; //记录某一层的结果
while(size--){
Node* node = que.front(); //获取要弹出的节点
que.pop(); //队列弹出
vec.push_back(node->val); //将弹出的节点数值放入数组中
for(int i = 0; i< node->children.size(); i++){
if(node->children[i]) que.push(node->children[i]);
}
}
result.push_back(vec); //将一层的数组放入到结果中
}
return result;
}
};
515.在每个树行中找大值 #力扣题目链接这道题,在每层进行比较即可获得大值即可。
class Solution {
public:
vectorlargestValues(TreeNode* root) {
queueque;
vectorresult;
if(root != NULL) que.push(root); //弹入根节点
while(!que.empty()){
int size = que.size(); //记录size个数
int max = INT32_MIN; //记录大值
while(size--){
TreeNode* node = que.front(); //获取要弹出的节点
que.pop(); //队列弹出
if(node->val >max){ //进行数值的比较,获得大值
max = node->val;
}
if(node->left) que.push(node->left); //获取这个节点的左孩子
if(node->right) que.push(node->right); //获取这个节点的右孩子
}
result.push_back(max);
}
return result;
}
};
116.填充每个节点的下一个右侧节点指针#力扣题目链接这里类似于链表操作,记录好上一个元素nodePre即可,之后将next指针指向下一个元素即可。
class Solution {
public:
Node* connect(Node* root) {
queueque;
if(root != NULL) que.push(root); //弹入根节点
while(!que.empty()){
int size = que.size(); //记录size个数
Node* nodePre;
Node* node;
for(int i = 0; inext = node;
nodePre = nodePre->next;
}
if(node->left) que.push(node->left); //获取这个节点的左孩子
if(node->right) que.push(node->right); //获取这个节点的右孩子
}
nodePre->next = NULL;
}
return root;
}
};
117.填充每个节点的下一个右侧节点指针2#力扣题目链接解题逻辑和116一模一样。
104.二叉树的大深度#力扣题目链接在遍历的同时,记录层数即可。
class Solution {
public:
int maxDepth(TreeNode* root) {
queueque;
int result = 0; //记录层数
if(root != NULL) que.push(root); //弹入根节点
while(!que.empty()){
int size = que.size(); //记录size个数
while(size--){
TreeNode* node = que.front(); //获取要弹出的节点
que.pop(); //队列弹出
if(node->left) que.push(node->left); //获取这个节点的左孩子
if(node->right) que.push(node->right); //获取这个节点的右孩子
}
result++;
}
return result;
}
};
111.二叉树的最小深度#力扣题目链接判断条件:当左右孩子为空时,说明到遍历的最低点了。
class Solution {
public:
int minDepth(TreeNode* root) {
if (root == NULL) return 0;
int result = 0;
queueque;
que.push(root);
while(!que.empty()) {
int size = que.size();
result++; // 记录最小深度
for (int i = 0; i< size; i++) {
TreeNode* node = que.front();
que.pop();
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
if (!node->left && !node->right) { // 当左右孩子都为空的时候
return result;
}
}
}
return result;
}
};
二、翻转二叉树题目:#力扣题目链接
给你一棵二叉树的根节点 root
,翻转这棵二叉树,并返回其根节点。
这道题解决的方法,先需要确定遍历方式,采用前序和后序遍历方式比较好,这里只需要进行左右孩子的交换即可。
class Solution {
public:
void traversal(TreeNode *cur, vector& dep){ //前序遍历
if(cur == NULL) return;
dep.push_back(cur->val); //中
swap(cur->left, cur->right); //交换左右孩子
traversal(cur->left, dep); //左
traversal(cur->right, dep); //右
}
TreeNode* invertTree(TreeNode* root) {
vectorresult;
traversal(root, result);
return root;
}
};
三、对称二叉树题目:#力扣题目链接
给你一个二叉树的根节点 root
, 检查它是否轴对称。
这道题判断是二叉树是否为对称二叉树,即左右孩子是否可以翻转不变,体现在外侧节点和内侧节点是否相等。
所以需要不停的判断左右孩子的信息,之后返回到根节点,这里采用遍历方式就应该只能采取后序遍历。
class Solution {
public:
bool compare(TreeNode* left, TreeNode* right){
//这里判断条件需要理解透彻,容易出错
if(left == NULL && right != NULL) return false;
else if(left != NULL && right == NULL) return false;
else if(left == NULL && right == NULL) return true;
else if(left->val != right->val) return false;
bool outside = compare(left->left, right->right);
bool inside = compare(left->right, right->left);
bool result = outside && inside;
return result;
}
bool isSymmetric(TreeNode* root) {
if(root == NULL) return true;
return compare(root->left, root->right);
}
};
四、总结和收获在这一章节,需要我们去了解二叉树几种遍历方式的特点,并在实现过程中有意识的去分析采用那种遍历方式。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧