二叉树常见面试题

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using std::cout;
using std::cin;

  struct TreeNode {
        int val;
      TreeNode *left;
      TreeNode *right;
      TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 };
//题目1.后继者
//设计一个算法,找出二叉搜索树中指定节点的“下一个”节点(也即中序后继)。
class Solution1 {
public:
    void Tree(TreeNode* root, TreeNode** ret, int* n)
    {
        if (root == nullptr)
        {
            return;
        }
        Tree(root->left, ret, n);
        ret[(*n)++] = root;
        Tree(root->right, ret, n);
    }
    int TreeSize(TreeNode* root)
    {
        if (root == nullptr)
        {
            return 0;
        }
        int leftSize = TreeSize(root->left);
        int rightSize = TreeSize(root->right);
        int sum = leftSize + rightSize + 1;
        return sum;
    }
    TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
        int Size = TreeSize(root);//计算二叉树大小
        TreeNode** ret = new TreeNode * [Size];
        int n = 0;
        Tree(root, ret, &n);
        TreeNode* next = NULL;
        for (int i = 0; i < n; i++)
        {
            if (ret[i] == p && i < n - 1)
            {
                next = ret[i + 1];
            }
        }
        return next;
    }
};
//树形DP套路口诀
//(1)假设以X节点为头,假设可以向X左树和X右树要任何信息
//(2)在上一步的假设下,讨论以X为头节点的树,得到答案的可能性(最重要)
//(3)列出所有可能性后,确定到底需要向左树和右树要什么样的信息
//(4)把左树信息和右树信息求全集,就是任何一棵子树都需要返回的信息S
//(5)递归函数都返回S,每一棵子树都这么要求

//题目2.平衡二叉树
//给定一个二叉树,判断它是否是高度平衡的二叉树。
//本题中,一棵高度平衡二叉树定义为:
//一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
int maxDepth(struct TreeNode* root) {
    if (root == NULL)
    {
        return 0;
    }
    int treeleft = maxDepth(root->left);
    int treeright = maxDepth(root->right);
    return treeleft > treeright ? treeleft + 1 : treeright + 1;
}
bool isBalanced(struct TreeNode* root) {
    if (root == NULL)
    {
        return true;
    }
    int treeleft = maxDepth(root->left);//判断左树是不是平衡二叉树
    int treeright = maxDepth(root->right);//判断右树是不是二叉树
    return abs(treeleft - treeright) < 2 && isBalanced(root->left) && isBalanced(root->right);
}
//题目3.树中节点间最远距离
//给定一棵二叉树的头节点head,任何两个节点之间都存在距离,给定一棵二叉树的头节点head,任何两个节点之间都存在距离
//返回整棵二叉树最大距离
struct Info3
{
    int MaxDistance;//记录节点中最大距离
    int height;
    Info3(int a, int b)
    {
        MaxDistance = a;
        height = b;
    }
};
class Solution3 {
public:
   
    Info3* Process3(TreeNode* head)
    {
        if (head == nullptr)
        {
            return new Info3(0, 0);
        }
        Info3* left = Process3(head->left);
        Info3* right = Process3(head->right);
        int height = fmax(left->MaxDistance, right->MaxDistance) + 1;
        int Distance = fmax(left->height + right->height + 1, fmax(left->MaxDistance, right->MaxDistance));
        delete left;
        delete right;
        return new Info3(Distance, height);
     }
    int MaxDistance(TreeNode* head)//主函数
    {
        return Process3(head)->MaxDistance;
    }
};
//题目4.最大二叉搜索
//给定一棵二叉树的头节点head,
//返回这颗二叉树中最大的二叉搜索子树的节点数量
struct Info4
{
    bool isALLBST;//是否是二叉搜素树
    int max;//记录最大节点
    int min;//记录最小节点
    int Sum;//最大二叉搜索树的节点个数
    Info4(bool s, int _max, int _min, int _Sum)
    {
        isALLBST = s;
        max = _max;
        min = _min;
        Sum = _Sum;
      
    }
};
class Solution4
{
public:
    Info4* Process4(TreeNode* head)
    {
        if (head == nullptr)
        {
            return nullptr;
        }
        Info4* left = Process4(head->left);
        Info4* right = Process4(head->right);
        int max = head->val;
        int min = head->val;
        if (left != nullptr)
        {
            max = fmax(max, left->max);
            min = fmin(min, right->min);
        }
        if (right != nullptr)
        {
            max = fmax(max, right->max);
            min = fmin(min, right->min);
        }
        bool s = false;//默认不是二叉搜素树
        int sum = 0;
        if (left != nullptr)
        {
            sum = left->Sum;
        }
        if (right != nullptr)
        {
            sum = right->Sum;
        }
        if (left == nullptr ? true : (left->isALLBST)
            && right == nullptr ? true : (right->isALLBST) 
            && left == nullptr ? true : (left->max<head->val)
            && right == nullptr ? true : (right->min>head->val)
            )
        {
            s = true;
            sum = (left == nullptr ? 0 : left->Sum) + (right == nullptr ? 0 : right->Sum) + 1;
           
        }
        delete left;
        delete right;
        return new Info4(s, max, min, sum);
    }
    int MaxBstSize(TreeNode* head)
    {
        return Process4(head)->Sum;
    }
};
//题目5.判断满二叉树
//给定一个数的头结点,返回这棵树是不是满二叉树
//技巧:满二叉树符合2^高度-1 = 节点个数
struct Info5
{
    int height;//记录树的高度
    int Sum;//记录节点的个数
    Info5(int _height, int _Sum)
    {
        height = _height;
        Sum = _Sum;
    }
};
class Solution5
{
public:
   Info5* Process5(TreeNode* head)
    {
       if (head == nullptr)
       {
           return new Info5(0, 0);
       }
       Info5* left = Process5(head->left);
       Info5* right = Process5(head->right);
       int height = fmax(left->height, right->height) + 1;
       int Sum = left->Sum + right->Sum + 1;
       delete left;
       delete right;
       return new Info5(height, Sum);
       }
   bool IsAllTree(TreeNode* head)
   {
       Info5* s = Process5(head);
       bool f = pow(2, s->height) == s->Sum;
       delete s;
       return f;
   }
};
  • 26
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 21
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1无名之辈1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值