day15 二叉树

102.二叉树的层序遍历

需要借助队列来实现,
先放入根节点,再将根节点弹出队列之后,再放入子节点

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> que;
        if(root!=NULL) que.push(root);  //如果根节点不为空 就放入队列中
        vector<vector<int>> result; //每一个元素是二叉树的每一层输出
        //控制二叉树的层序遍历
        while(!que.empty()){    
            int size=que.size();
            vector<int> vec;    //用来存放每次弹出的元素
            //控制每一层的根节点弹出 并加入子节点
            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.二叉树的层次遍历 II

跟上题相比就是vector<vector> result中每一个元素的位置从头到尾反转一下
只需要在最后返回之前,将元素的值进行反转

reverse(result.begin(),result.end());

199.二叉树的右视图

右视图其实就是每一层最后的节点值,刚开始理解错了,以为是右节点的元素值,遍历每层时,弹出最后一个就行

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        queue<TreeNode*> que;
        if(root!=NULL) que.push(root);  //如果根节点不为空 就放入队列中
        vector<int> vec;    //用来存放每次弹出的元素
        //控制二叉树的层序遍历
        while(!que.empty()){    
            int size=que.size();
            //控制每一层的根节点弹出 并加入子节点
            while(size--){  
                TreeNode* node=que.front(); //弹出本层的元素
                que.pop();
                if(size==0){	//将每一层的最后一个元素存入数组中
                     vec.push_back(node->val);
                }
                if(node->left){
                    que.push(node->left);
                }
                if(node->right){
                    que.push(node->right);
                }
            }
        }
        return vec;
    }
};

637.二叉树的层平均值

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        queue<TreeNode*> que;
        if(root!=NULL) que.push(root);  //如果根节点不为空 就放入队列中
        vector<double> result; //每一个元素是二叉树的每一层输出
        //控制二叉树的层序遍历
        while(!que.empty()){    
            int size=que.size();
            int n=size;
            double sum=0;    //用来存放每层的和
            //控制每一层的根节点弹出 并加入子节点
            while(size--){  
                TreeNode* node=que.front(); //弹出本层的元素
                que.pop();
                sum+=node->val;
                if(node->left){ //如果子节点不为空 就加到队列中
                    que.push(node->left);
                }
                if(node->right){
                    que.push(node->right);
                }
            }
            result.push_back(sum/n);
        }
        return result;
    }
};

429.N叉树的层序遍历

还是模板,在添加字节点值时添加的是一个节点的多个孩子

class Solution {
public:
    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;
            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:
    vector<int> largestValues(TreeNode* root) {
        queue<TreeNode*> que;
        if(root!=NULL) que.push(root);  //如果根节点不为空 就放入队列中
        vector<int> result; //每一个元素是二叉树的每一层输出
        //控制二叉树的层序遍历
        while(!que.empty()){    
            int size=que.size();
            vector<int> vec;    //用来存放每次弹出的元素
            //控制每一层的根节点弹出 并加入子节点
            int maxValue=INT_MIN;
            while(size--){  
                TreeNode* node=que.front(); //弹出本层的元素
                que.pop();
                //比较每次队列弹出元素的大小 
                maxValue=node->val>maxValue ? node->val:maxValue;

                if(node->left){ //如果子节点不为空 就加到队列中
                    que.push(node->left);
                }
                if(node->right){
                    que.push(node->right);
                }
            }
            result.push_back(maxValue);
        }
        return result;
    }
};

226.翻转二叉树(递归方法)

顺序问题:
翻转二叉树使用前序和后序都可以,不能使用中序,中序在翻转左子树的节点之后,又经过中间节点的翻转,左子树和右子树交换位置,原来的左子树又一次翻转,而原来的右子树没有改变
1.确定递归函数的参数和返回值(是每一个节点)

 TreeNode* invertTree(TreeNode* root)

2.确定每一次递归终止条件

if(root==NULL) return root;

3.确定单层的递归的逻辑
先交换子节点的顺序,再进行递归

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(root==NULL) return root;
        swap(root->left,root->right);
        invertTree(root->left);
        invertTree(root->right);
        return root;
    }
};

101. 对称二叉树(递归方法)

思路:比较的是左子树和右子树,在遍历的过程中,需要同时遍历两棵树
只能采用后序遍历,需要通过函数的返回值去判断,两棵树的内侧节点和外侧节点是否相等
递归三部曲
1.确定递归函数的参数和返回值
返回值是bool类型,判断左子树和右子树是否相等
2.终止条件
节点为空的情况有:(左、右节点不是左右孩子,指的是左右子树)

  • 左右节点有一个为空,不对称,return false
  • 左右都为空,对称,返回true
  • 左右都不为空,比较数值是否相等,不相同就返回false

3.确定单层递归的逻辑(就是处理左右节点都不会空,且数值相同的情况)

  • 比较二叉树的外侧是否对称:传入的是左节点的左孩子,右节点的有孩子
  • 比较内测是否对称:传入的是左节点的右孩子,右节点的左孩子
  • 如果左右都对称就返回true,有一侧不对称就返回false
class Solution {
public:
    bool compare(TreeNode* left,TreeNode* right){
        //排除左右不对称的情况
        if(left==NULL && right!=NULL) return false;
        else if(left!=NULL && right==NULL) return false;
        //两边都为空就是true
        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 isSame=outside&inside;
        return isSame;
    }

    bool isSymmetric(TreeNode* root) {
        if(root==NULL) return true;
        return compare(root->left,root->right);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值