基础算法--二叉树

0 阅读2分钟

二叉树


二叉树是也是一种经典的数据结构,在算法题目中,二叉树的题目多是基于递归的

先给大家介绍几个关于二叉树的小结论;

  • 一共有n个节点的二叉树,如果度为0的节点为x个,那么度为2的节点有x-1个
  • 有一个先序遍历序列:1 2 3 4,一共有C2nnn+1\frac{C_{2n} ^n}{n+1}(n=4)颗二叉树满足(卡特兰数)
  • 先序+中序,确定一颗二叉树

我们来看一道例题;

二叉树.png

分析: 我们考虑一下一棵树什么时候是镜像对称的,其实就是左子树和右子树镜像对称。 那么该怎么用代码进行判断呢? 可以用两个指针p,q对称地递归遍历树,进行比较即可。

  1. 初始化:p=root->l,q=root->r
  2. 递归出口:p,q都为空,return 0
  3. 递归条件:p == q,p->l == q->r,p->r == q->l 特殊情况:空树也满足条件

下面是代码示例:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool check(TreeNode* p, TreeNode* q) {
        if(p == nullptr && q == nullptr){
            return 1;
        }
        if(!p || !q){
            return 0;
        }

        return (p->val == q->val) && check(p->left, q->right) && check(p->right, q->left);
    }

    bool checkSymmetricTree(TreeNode* root) {
        if(root == nullptr){
            return 1;
        }
        else{
            return check(root->left, root->right);
        }
    }
};

再来看一道题目:

二叉树-1.png

分析: 我们找两个节点的最近公共祖先,一定和这两个节点的位置关系有关

  • 如果p,q分别出现在root的左右子树中,则root是答案
  • 如果p,q同时出现在root的某一个子树x中,则问题转换为在x树中找公共祖先(递归) 递归函数(root, p, q):在以root为根的树中找p,q
  1. root == NULL,空树,返回NULL
  2. root == p或者root == q,找到了一个,直接返回root。若另一个在root的子树中,root是答案。若不在,则返回找到的这个节点
  3. root不为空,也不是p,q,说明p,q在root的左右子树中,则递归调用,分别去左右子树中找。 l = f(root->left, p, q) r = f(root->right, p, q) (1)若l,r全为空,返回空 (2)若l,r有一个为空,返回另一个。说明在另一个子树中找到了p,q或者答案 (3)若l,r都不为空,说明p,q一边一个,则root是答案,返回root

下面是代码演示:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root == NULL){
            return NULL;
        }
        if(root == p || root == q){
            return root;
        }

        TreeNode* l = lowestCommonAncestor(root->left, p, q);
        TreeNode* r = lowestCommonAncestor(root->right, p, q);
        if(l == NULL){
            return r;
        }
        if(r == NULL){
            return l;
        }
        if(l && r){
            return root;
        }
        return NULL;
    }
};