Bootstrap

完全二叉树节点的数量 平衡二叉树

1.给出一个完全二叉树,求出该树的节点个数

#include <bits/stdc++.h>
using namespace std;
struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x)
    {
        val=x;
        left=NULL;
        right=NULL;
    }
};
int getnode(TreeNode* root)
{
    if(root==NULL)
    return 0;
    int leftdepth=0;
    int rightdepth=0;
    TreeNode* left=root->left;
    TreeNode* right=root->right;
    while(left)
    {
        left=left->left;
        leftdepth++;
    }
    while(right)
    {
        right=right->right;
        rightdepth++;
    }
    if(leftdepth==rightdepth)
    {
        return (2<<leftdepth)-1;
    }
    int leftnum=getnode(root->left);
    int rightnum=getnode(root->right);
    return (leftnum+rightnum)+1;
    
}
int main()
{
    TreeNode* root=new TreeNode(21);
    root->left=new TreeNode(87);
    root->right=new TreeNode(7);
    root->left->left=new TreeNode(2);
    root->left->right=new TreeNode(1);
    root->left->left->left=new TreeNode(5);
    root->left->left->right=new TreeNode(4);
    root->left->right->left=new TreeNode(9);
    root->left->right->right=new TreeNode(8);
    root->right->left=new TreeNode(7);
    root->right->right=new TreeNode(6);
    cout<<getnode(root);
    return 0;
 } 

思路:对于求完全二叉树节点,可以使用求满二叉树的公式2的n次方减1,这里n指的是满二叉树的深度,为什么要用满二叉树的公式,其实我们可以来想,完全二叉树如果不是满二叉树,那么它左右子树深度一定不同,那么此时我们就分别求它左右子树的节点,因为此时它的左右子树必定是满二叉树,最后再加上根节点,就得到了完全二叉树的节点数。

这里我们用后序遍历的方法,里面用指针来进行遍历,根存在的情况下,先遍历左子树,然后左子树的左子树,一直到左子树为空,能够得到左子树的深度,而之后相应地遍历右子树,然后是右子树地右子树,一直到最后,得到右子树的深度。之所以只遍历两端的节点,其实是因为其余节点不值得遍历,只要其左端的左节点和右端的右节点存在,根据其是完全二叉树的特性,就不用遍历其余节点,因为肯定存在。

最后得到左右子树的深度,进行比较,如果相等就利用公式计算总结点,否则就分别计算左子树的总结点和右子树的总结点,,求它们的和再加上根节点。

2.给定一个二叉树,判断它是否是高度平衡的二叉树。

#include <bits/stdc++.h>
using namespace std;
struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x)
    {
        val=x;
        left=NULL;
        right=NULL;
    }
};
int get_height(TreeNode* root)
{
    if(root==NULL)
    return 0;
    int leftheight=get_height(root->left);
    if(leftheight==-1)
    {
        return -1;
    }
    int rightheight=get_height(root->right);
    if(rightheight==-1)
    {
        return -1;
     } 
    return abs(leftheight-rightheight)>1?-1:1+max(leftheight,rightheight);
    
 } 
bool balance(TreeNode* root)
{
    if(get_height(root)==-1)
    return false;
    
    return true;
}
int main()
{
    TreeNode* root=new TreeNode(1);
    root->left=new TreeNode(2);
    root->right=new TreeNode(3);
    root->left->left=new TreeNode(4);
    root->left->right=new TreeNode(5);
    get_height(root);
    cout<<balance(root);
    
    return 0;
}
 

思路:首先我们要知道什么是平衡二叉树,即左右子树高度差不大于1,所以我们需要遍历整棵树比较每个节点的左右子树高度差,只要有一个高度差大于1,那么整棵树就不是平衡二叉树。

在这里我们可以记一下,求高度用后序遍历,求深度用前序遍历。这里我们要求高度,因此用后序遍历来解决问题。

根存在情况下,先递归遍历根节点的左子树求左子树高度,其次是根节点右子树高度,然后比较两者的高度,高度差大于1就返回-1,否则就返回根节点的高度。最后判断如果得到-1就说明不是平衡二叉树,否则就是平衡二叉树。

;