二叉树相关知识(c++)【未完结】

1,求深度:
递归思想,一个点的深度 = 子树最大深度+1
【本质是DFS后序遍历】

class Solution {
public:
    int maxDepth(TreeNode* root) 
    {
        if(root == NULL)
           return 0;
        else
            return max(maxDepth(root->left),maxDepth(root->right))+1;
    }
};

2,求是不是平衡二叉数
跟上一个相关,其实平衡二叉树就是求两个子树的深度差是否大于2

class Solution {
public:
    int getdepth(TreeNode* root)
    {
        if(root == NULL)
        return 0;
        return max(getdepth(root -> left),getdepth(root -> right)) + 1;
    }
    bool isBalanced(TreeNode* root) 
    {
        if(root == NULL)
           return true;
        return abs(getdepth(root -> right) - getdepth(root -> left)) < 2 && isBalanced(root -> left) && isBalanced(root->right);
    }
};

3,重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例:
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

得出二叉树:
在这里插入图片描述
其实这个原理非常之简单,就是前中后序遍历的
前:根—>左节点—>右节点
中:左节点—>根—>右节点
后:左节点—>右节点—>根
递归的分析,前序的第一个就是根节点,根节点在中序出现的位置分割了左子树和右子树。
但是写起来很麻烦很麻烦很麻烦,我的代码也是copy大佬的

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
    {
        return temp(preorder.begin(),preorder.end(),inorder.begin(),inorder.end());
    }
    TreeNode* temp(vector<int>::iterator prebegin,vector<int>::iterator prend,vector<int>::iterator inbegin,vector<int>::iterator inend)
    {
        if(inbegin == inend)
           return NULL;
        TreeNode* node = new TreeNode(*prebegin); 
        auto root = find(inbegin,inend,*prebegin);
        node -> left = temp(prebegin+1,prebegin+1+(root-inbegin),inbegin,root);
        node -> right = temp(prebegin+1+(root-inbegin),prend,root+1,inend);
        return node;
    }
};

4,二叉树的层序遍历(BFS)
非递归实现嗷,用队列

class Solution {
public:
    vector<int> levelOrder(TreeNode* root) 
    {
        queue<TreeNode*> q;
        vector<int> result;
        if(root == NULL)
        return result;
        q.push(root);
        while(!q.empty())
        {
           TreeNode* temp = q.front();
           q.pop();
            if(temp ->left)
              q.push(temp->left);
            if(temp -> right)
              q.push(temp->right);
            result.push_back(temp->val);
        }
        return result;
    }
};

5,寻找最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

方法:
用了递归——其实这题挺难想明白的,我想了好久
如果是用递归,那我们需要先考虑普通情况,再考虑边界情况
普通情况:
在这里插入图片描述
如果左子树返回了值,而右子树没有,则说明此左子树的结点就是所求——反之亦然
如果左子树和右子树同时返回了,则返回这个结点本身
递归的分析,知道折腾到底又折腾上来
直接上代码吧,这题真解释不清楚

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 
    {
        if(root == NULL)
            return NULL;
        if(root == p || root == q)
            return root;
        TreeNode* left = lowestCommonAncestor(root->left,p,q);
        TreeNode* right = lowestCommonAncestor(root->right,p,q);
        if(left == NULL)
            return right;
        if(right == NULL)
            return left;
        if(left && right)
            return root;
        return NULL;
    }
};

6,对称二叉树

给定一个二叉树,检查它是否是镜像对称的。

用递归做的!
这个好理解!看源码就行!

class Solution {
public:
    bool compare(TreeNode* left,TreeNode* right)
    {
        if(left == NULL && right != NULL)
            return false;
        if(right == NULL && left != NULL)
            return false;
        if(left == NULL && right == NULL)
            return true;
        if(left->val != right -> val )
            return false;
        else
            return compare(left->left,right->right) && compare(left->right,right->left);
    }
    bool isSymmetric(TreeNode* root) 
    {
        if(root == NULL)
            return true;
        return compare(root->left,root->right);
    }
};

其实迭代也可以做的——原理跟层序遍历差不多,运用队列比较每一层是否相同
但是不能直接比(我第一次就是每一层全扫进去然后看是否对称),如果这样的话,不能确定左右位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值