【数据结构】二叉树基础OJ题

举报
平凡的人1 发表于 2022/10/18 19:46:30 2022/10/18
【摘要】 二叉树相关OJ题目练习,你值得学习

题目来源:牛客网和力扣

话不多说,直接开始我们的主题👇

单值二叉树

image-20220816165306558

简单来说,结点的值都要相同。那我们可以去判断当前结点的值和左孩子的值相不相同,再去判断当前结点的值和右孩子的值相不相同。只要出现不同,那我们直接返回错误。再去递归左右孩子,直到结束。

bool isUnivalTree(struct TreeNode* root){
    if(root == NULL)
    {
        return true;
    }
    else if(root->left!=NULL&&root->val != (root->left)->val)
    {
        return false;
    }
    else if(root->right!=NULL&&root->val!=(root->right)->val)
    {
        return false;
    }
    return isUnivalTree(root->left)&&isUnivalTree(root->right);
}

image-20220816170259271

这里有一个比较容易错的地方:判断的时候除了要判断结点的值是否相等之外,左右孩子必须是存在的!

相同的树

image-20220816171413835

两棵树分别去比较(都为空肯定相等,其中一个为空就不相等),根的值比较,对应的子树比较。还是采用递归解决

bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    if(p==NULL&&q==NULL)
    {
        return true;
    }
    if(p==NULL||q==NULL)
    {
        return false;
    }
    if(p->val!=q->val)
    {
        return false;
    }
    return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}

image-20220816172823677

另一棵树的子树

image-20220816173147187

这是一个很有意思的题目,我们可以让原树中的每颗子树(包括原树)去和subRoot比较。怎么比较❓我们可以利用上面的题相同的树去的函数进行判断。让原树的每个子树去比较即可

bool isSametree(struct TreeNode*p,struct TreeNode*q)
{
    if(p==NULL&&q==NULL)
    {
        return true;
    }
    if(p==NULL||q==NULL)
    {
        return false;
    }
    if(p->val!=q->val)
    {
        return false;
    }
    return isSametree(p->left,q->left)&&isSametree(p->right,q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
    if(root==NULL)
    {
        return false;
    }
    if(isSametree(root,subRoot))
    {
        return true;
    }
    return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}

image-20220816174148980

二叉树的前序遍历

image-20220816174430690

这道题可不是简单的打印出前序遍历。我们需要把结果存放在开辟的数组中。我们可以通过算出结点的个数开辟对应的空间。再根据前序遍历把结果放到数组中:

int TreeSize(struct TreeNode*root)
 {
     if(root==NULL)
     {
         return 0;
     }
     return TreeSize(root->left)+TreeSize(root->right)+1;
 }
 void PreOrder(struct TreeNode*root,int*a,int*pi)
 {
     if(root == NULL)
     {
         return;
     }
     a[*pi] = root->val;
     (*pi)++;
     PreOrder(root->left,a,pi);
     PreOrder(root->right,a,pi);
            
 }
int* preorderTraversal(struct TreeNode* root, int* returnSize){
    int n = TreeSize(root);
    int*arr = (int*)malloc(sizeof(int)*n);
    int i = 0;
    PreOrder(root,arr,&i);
     *returnSize = n;
    return arr;
}

image-20220816175058524

趁热打铁

二叉树的中序遍历

image-20220816182021690

一样的做法:

 int TreeSize(struct TreeNode*root)
 {
     if(root==NULL)
     {
         return 0;
     }
     return TreeSize(root->left)+TreeSize(root->right)+1;
 }

 void InOrder(int*arr,struct TreeNode*root,int*pi)
 {
     if(root==NULL)
     {
         return;
     }
    InOrder(arr,root->left,pi);
     arr[*pi] = root->val;
     (*pi)++;
     InOrder(arr,root->right,pi);
 }

int* inorderTraversal(struct TreeNode* root, int* returnSize){
    int n = TreeSize(root);
    int*arr = (int*)malloc(sizeof(int)*n);
    int i = 0;
    InOrder(arr,root,&i);
    *returnSize = n;
    return arr;
}

image-20220816182054491

二叉树遍历

image-20220816182221449

题目要求很简单:给出前序遍历,让我们建立二叉树,最后进行中序遍历输出。

我们得先了解怎么去建立,我们以上面的示例1为例子:

image-20220816183204838

代码实现:

#include <stdio.h>
#include <stdlib.h>

typedef char BTDataType;
typedef struct BinarryTree
{
    struct BinarryTree*left;
    struct BinarryTree*right;
    BTDataType data;
}BTNode;

BTNode* BinarryTreeCreate(BTDataType* str,int*pi)
{
    if(str[*pi]=='#')
    {
        (*pi)++;
        return NULL;
    }
    BTNode*root = (BTNode*)malloc(sizeof(BTNode));
    if(NULL == root)
    {
        perror("malloc fail");
        exit(-1);
    }
    root->data = str[*pi];
    (*pi)++;
    root->left = BinarryTreeCreate(str,pi);
    root->right = BinarryTreeCreate(str,pi);
    return root;
}

void InOrder(BTNode*root)
{
    if(root==NULL)
        return;
    InOrder(root->left);
    printf("%c ",root->data);
    InOrder(root->right);
}

int main()
{
    char str[101];
    gets(str);
    int i = 0;
    BTNode*root = BinarryTreeCreate(str,&i);
    InOrder(root);
    return 0;
}

image-20220816184754067

平衡二叉树

image-20220816195925457

这道题我的思路是求出左子树的高度和右子树的高度,判断差值,大于1就直接返回false,然后再去递归左子树和右子树

int TreeDepth(struct TreeNode*root)
{
    if(root==NULL)
    {
        return 0;
    }
    int left = TreeDepth(root->left);
    int right = TreeDepth(root->right);
    return left>right?left+1:right+1;
}
bool isBalanced(struct TreeNode* root){
    if(root == NULL||(root->left==NULL)&&(root->right==NULL))
        return true;
    if(abs(TreeDepth(root->left)-TreeDepth(root->right))>1)
        return false;
    return isBalanced(root->left)&&isBalanced(root->right);
}

image-20220816200159142

对称二叉树

image-20220816200356592

如果是对称二叉树的话,那么左子树和右子树同时为空,左结点的左值会等于右结点的右值,左结点的右值会等于右结点的左值。我们可以采用递归的方式来完成这道题:

bool judge(struct TreeNode* left,struct TreeNode* right){
    if(left == NULL && right == NULL)
        return true;
    if(left == NULL || right == NULL || left -> val != right -> val)
        return false;
    return judge(left -> left,right -> right) && judge(left -> right,right -> left);
}

bool isSymmetric(struct TreeNode* root){
    if(root == NULL)
        return true;
    return judge(root -> left,root ->right);
}

翻转二叉树

image-20220816232225736

实际上就是左右子树进行交换即可:

struct TreeNode* invertTree(struct TreeNode* root){
    if(root==NULL)
        return NULL;
    struct TreeNode*tmp = root->left;
    root->left = root->right;
    root->right = tmp;

    invertTree(root->left);
    invertTree(root->right);
    return root;
}

image-20220816233126531


结语

通过这几道简单的题目,我们对于递归有了进一步的理解,同时加深了对二叉树的理解,如果觉得自己学有余力的情况之下,我们还可以去做更多的题目,当然,这里的二叉树知识是比较基础的,后面会更进一步的学习,这次就先到这里结束了

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。