代码随想录第15天:二叉树-创新互联

一、层序遍历

  层序遍历,是按照层数从低到高,同一层从左到右遍历。在这里采用递归法是无法做到的,观察遍历的特点,这里需再加一个队列来实现。

天津网站制作公司哪家好,找创新互联!从网页设计、网站建设、微信开发、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元起,快前往官网查看详情吧

网站栏目:代码随想录第15天:二叉树-创新互联
文章起源:https://www.cdcxhl.com/article40/deehho.html

成都网站建设公司_创新互联,为您提供企业建站域名注册搜索引擎优化定制开发网站建设网站营销

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

外贸网站建设