【代码随想录_Day11】 一共八道题

以下是今日份的总结

102.二叉树的层序遍历
107.二叉树的层次遍历II
199.二叉树的右视图
637.二叉树的层平均值
429.N叉树的层序遍历
515.在每个树行中找最大值
116.填充每个节点的下一个右侧节点指针
117.填充每个节点的下一个右侧节点指针II

102|107|116|117|199|429|515|637|层序遍历的递归和迭代法非常重要 ^ _ ^

二叉树的层序遍历

思路:

按照二叉树从上到下的顺序一层一层的向下遍历

值得注意的是

辅助队列对此帮助很大

迭代:

vector<vector<int>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>> v;
        queue<TreeNode*> que;
        if (root == NULL)
            return v;
        que.push(root);while (!que.empty()) {
            vector<int> vec;
            for (int i = que.size(); i > 0; i--) {
                root = que.front(); // 当前根节点是队列里的头位
                que.pop();          // 出队
                vec.push_back(root->val);
                if (root->left != NULL) {
                    que.push(root->left); // 有左节点就入队
                }
                if (root->right != NULL) {
                    que.push(root->right); // 有右节点就入队
                }
            }
            v.push_back(vec); // 把该层节点集放入容器
        }
        
        return v;
}

递归:

    void order(TreeNode* node,vector<vector<int>> &vec,int depth){
        if(node ==nullptr) return;
        if(vec.size()==depth) vec.push_back(vector<int>());
        vec[depth].push_back(node->val);
        order(node->left, vec,depth+1);
        order(node->right, vec,depth+1);
    }
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        int depth = 0;
        vector<vector<int>>result;
        order(root, result, depth);
     
        return result;
    }

二叉树的层序遍历 II

思路:

自下而上,层序遍历,reverse

值得注意的是

reverse()

迭代:

vector<vector<int>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>> v;
        queue<TreeNode*> que;
        if (root == NULL)
            return v;
        que.push(root);while (!que.empty()) {
            vector<int> vec;
            for (int i = que.size(); i > 0; i--) {
                root = que.front(); // 当前根节点是队列里的头位
                que.pop();          // 出队
                vec.push_back(root->val);
                if (root->left != NULL) {
                    que.push(root->left); // 有左节点就入队
                }
                if (root->right != NULL) {
                    que.push(root->right); // 有右节点就入队
                }
            }
            v.push_back(vec); // 把该层节点集放入容器
        }
        reverse(v.begin(), v.end());
        return v;
}

递归:

    void order(TreeNode* node,vector<vector<int>> &vec,int depth){
        if(node ==nullptr) return;
        if(vec.size()==depth) vec.push_back(vector<int>());
        vec[depth].push_back(node->val);
        order(node->left, vec,depth+1);
        order(node->right, vec,depth+1);
    }
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        int depth = 0;
        vector<vector<int>>result;
        order(root, result, depth);
        reverse(result.begin(), result.end());
        return result;
    }

二叉树的右视图

思路:

层序遍历,但是只将每层最后一位加入vector

值得注意的是

对根结点为NULL的情况要注意判断

迭代:

    vector<int> rightSideView(TreeNode* root) {
        queue<TreeNode*> que;
        vector<int> res;
        if (root != nullptr) que.push(root);
        while (!que.empty()) {
            int levelSize = que.size();
            for (int i = 0; i < levelSize; ++i) {
                TreeNode* currentNode = que.front();
                que.pop();
                if (i == levelSize - 1) {
                    res.push_back(currentNode->val);
                }
                if (currentNode->left != nullptr) {
                    que.push(currentNode->left);
                }
                if (currentNode->right != nullptr) {
                    que.push(currentNode->right);
                }
            }
        }
        return res;
    }

二叉树的层平均值

思路:

层序遍历,然后对每一层的节点值做平均值处理

值得注意的是

节点值为double方便平均值计算

迭代:

    vector<double> averageOfLevels(TreeNode* root) {
        queue<TreeNode*>que;
        if(root !=NULL) que.push(root);
        vector<double> vd;
        while(!que.empty()){
            int size = que.size();//队列长度
            double sum = 0;//当前层节点值总和
            for(int i = 0;i<size;i++){
                TreeNode* node = que.front();
                sum+=node->val;
                que.pop();//中
                if(node->left)que.push(node->left);//左
                if(node->right)que.push(node->right);//右
            }
            vd.push_back(sum/size);//压入平均值
        }
        return vd;
    }

递归:

	 void order(TreeNode* node,vector<vector<double>> &vec,int depth){
        if(node == nullptr)return;
        if(vec.size() == depth) vec.push_back(vector<double>());
        vec[depth].push_back(node->val);
        order(node->left,vec,depth+1);
        order(node->right,vec,depth+1);
    }
    vector<double> averageOfLevels(TreeNode* root) {
        vector<vector<double>> vd;
        vector<double>v;
        int depth = 0;
        order(root,vd,depth);
        for(int i = 0;i<vd.size();i++){
            double vall =0;
            for(double val:vd[i]){               
                vall +=val;  
            }
            v.push_back(vall/vd[i].size());
        }
        return v;
    }

N叉树的层序遍历

思路:

和二叉树的层序遍历一样,在递归部分把left、right替换成children的遍历

值得注意的是

子节点不再最多为两个

迭代:

    vector<vector<int>> levelOrder(Node* root) {
        queue<Node*> 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++) {
                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;
    }

递归:

    void order(Node* node,vector<vector<int>>&vec,int depth){
        if(node==nullptr)return;
        if(vec.size()==depth) vec.push_back(vector<int>());
        vec[depth].push_back(node->val);//压入当前节点值
        vector<Node*>v;
        v = node->children;
        //替换了二叉树左右子树递归
        for(int i = 0;i<v.size();i++){
            order(v[i],vec,depth+1);
        }
    }
    vector<vector<int>> levelOrder(Node* root) {
        vector<vector<int>>result;
        int depth = 0;
        order(root,result,depth);
        return result;
    }

在每个树行中找最大值

思路:

层序遍历,但是在途中对每一层的节点元素做比较,记录最大值

值得注意的是

节点存在负值

迭代:

   vector<int> largestValues(TreeNode* root) {
        queue<TreeNode*>que;
        vector<int>res;
        if(root!=NULL){
            que.push(root);
        }
        while(!que.empty()){
            int size = que.size();
            int maxValue = INT_MIN;//树的value要考虑到有负值
            for(int i = 0;i<size;i++){
                TreeNode* node = que.front();
                que.pop();

                maxValue = std::max(maxValue,node->val);
                if(node->left)que.push(node->left);
                if(node->right)que.push(node->right);
            }
        res.push_back(maxValue);
        }
        return res;
    }

递归:

    void levelOrder(TreeNode* node,vector<vector<int>>&vec,int depth){
        if(node==nullptr)return;
        if(depth==vec.size()){
            vec.push_back(vector<int>());
        }
        vec[depth].push_back(node->val);
        levelOrder(node->left, vec,  depth+1);
        levelOrder(node->right, vec,  depth+1);
    }
    vector<int> largestValues(TreeNode* root) {
        vector<vector<int>> res;
        vector<int>result;
        int depth = 0;
        levelOrder(root, res, depth);
        for(vector<int>cur:res){
            int max = 0 ;
            for(int i = 0;i<cur.size();i++){
                if(i==0){
                    max=cur[0];
                    continue;
                }
                max = std::max(max,cur[i]);
            }
            result.push_back(max);
        }
        return result;
    }

填充每个节点的下一个右侧节点指针

本题讨论的是完全二叉树,但是解题方法按一般情况来看,可以覆盖完全二叉树。

思路:

层序遍历,然后对节点的next进行指向

值得注意的是

当前层末尾的节点指向NULL

迭代:

    Node* connect(Node* root) {
        queue<Node*> que;
        if (root != NULL) que.push(root);
        while (!que.empty()) {
            int size = que.size();
            // vector<int> vec;
            Node* nodePre;
            Node* node;
            for (int i = 0; i < size; i++) {
                if (i == 0) {
                    nodePre = que.front(); // 取出一层的头结点
                    que.pop();
                    node = nodePre;
                } else {
                    node = que.front();
                    que.pop();
                    nodePre->next = node; // 本层前一个节点next指向本节点
                    nodePre = nodePre->next;
                }
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
            nodePre->next = NULL; // 本层最后一个节点指向NULL
        }
        return root;

    }

递归:

    void order(Node* node,vector<vector<Node*>>& vec,int depth){
        if(node==nullptr)return;
        if(depth==vec.size())vec.push_back(vector<Node*>());
        vec[depth].push_back(node);
        order(node->left, vec, depth+1);
        order(node->right,vec,depth+1);
    }
    Node* connect(Node* root) {
        if(root==nullptr)return root;
        vector<vector<Node*>> vec;
        //Node* res = new Node();
        int depth = 0;
        order(root, vec, depth);
        for(vector<Node*>tmp:vec){
            for(int i = 0;i<tmp.size();i++){
                if(i==tmp.size()-1)tmp[i]->next=NULL;
                else{
                    tmp[i]->next=tmp[i+1];
                }
            }
        }
        return root;
    }

填充每个节点的下一个右侧节点指针 II

思路:

层序遍历,然后对节点的next进行指向

值得注意的是

当前层末尾的节点指向NULL

迭代:

    Node* connect(Node* root) {
        queue<Node*> que;
        if (root != NULL) que.push(root);
        while (!que.empty()) {
            int size = que.size();
            vector<int> vec;
            Node* nodePre;
            Node* node;
            for (int i = 0; i < size; i++) {
                if (i == 0) {
                    nodePre = que.front(); // 取出一层的头结点
                    que.pop();
                    node = nodePre;
                } else {
                    node = que.front();
                    que.pop();
                    nodePre->next = node; // 本层前一个节点next指向本节点
                    nodePre = nodePre->next;
                }
                if (node->left) que.push(node->left);
                if (node->right) que.push(node->right);
            }
            nodePre->next = NULL; // 本层最后一个节点指向NULL
        }
        return root;
    }

递归:

    void order(Node* node,vector<vector<Node*>>& vec,int depth){
        if(node==nullptr)return;
        if(depth==vec.size())vec.push_back(vector<Node*>());
        vec[depth].push_back(node);
        order(node->left, vec, depth+1);
        order(node->right,vec,depth+1);
    }
    Node* connect(Node* root) {
        if(root==nullptr)return root;
        vector<vector<Node*>> vec;
        int depth = 0;
        order(root, vec, depth);
        for(vector<Node*>tmp:vec){
            for(int i = 0;i<tmp.size();i++){
                if(i==tmp.size()-1)tmp[i]->next=NULL;
                else{
                    tmp[i]->next=tmp[i+1];
                }
            }
        }
        return root;
    }

写在最后

----OK,今日份的博客就写到这里,这一期的题全是层序遍历,明天继续加油!!!
—看了看下期的题,以后的二叉树就没这么轻松了;
–追上时间进度了吗?如追,从欠四天变成欠三天!!(笑
-风从我脚边溜走,没有告别。

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值