LeetCode-二叉树

 1、判断单值二叉树

. - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
 bool _isUnivalTree(struct TreeNode* root,int data)
{
    if(root==NULL)
    {
        return true;//空不影响,不为空的节点才影响
    }
    if(root->val!=data)
    {
        return false;
    }
    return _isUnivalTree(root->left,data)&&_isUnivalTree(root->right,data);
}
bool isUnivalTree(struct TreeNode* root) {
    int data=root->val;
    return _isUnivalTree(root,data);
}
//先记录下根节点的数据,再利用递归去和左右子树的节点数据比较;

 先记录根节点的值,将这个值作为参照标准;

定义一个新的函数,依次拿根节点的值和左右节点的值去和data值比较,若是不同则返回false,反之则继续递归比较,当root为空的时候,就说明比较完了,比较完还没有不一样的就返回true;

2、二叉树的最大深度

. - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
 
int maxDepth(struct TreeNode* root) {
    if(root==NULL)
    {
        return 0;
    }
    int lefth=maxDepth(root->left);
    int righth=maxDepth(root->right);//左右子树的高度

    return lefth>righth?lefth+1:righth+1;
}
//若根节点不是NULL,就返回左右子树里面高度更高的一个再加上1,这个1是根节点的那一层

最大深度就是高度;

一颗二叉树的高度等于最上面的一层加上左右子树里面较高的一颗子树高度;

若是根节点不是空就返回左右子树里面更高的一个树的高度再加上1,1是根节点层高;直到根节点为空就说明遍历完成。

注意这里使用临时变量接收左右子树的高度是为了避免计算次数过多,当直接拿函数调用来比较并且返回的时候,每一次都要重新递归调用,这样运算次数过多可能会出现超出时间限制的报错。

3、二叉树的前序遍历

. - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* _preorderTraversal(struct TreeNode* root, int* a,int* pi)
 {
    if(root==NULL)
        return NULL;
    
        a[(*pi)++]=root->val;
        _preorderTraversal(root->left,a,pi);
        _preorderTraversal(root->right,a,pi);  
        return a; 
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
    int* a=(int*)malloc(sizeof(int)*100);
    *returnSize=0;
    _preorderTraversal(root,a,returnSize);
    return a;
}

本题是将一个二叉树里面的节点以前序遍历的排序方式排列并且数组的形式返回;

首先要开辟一个数组,returnSize是数组里面存放的节点个数,也相当于是数组里面有效数据的个数;每次放入节点数据进入数组之后,把下标returnSize加加,方便下依次放数据的时候访问到数组的下一个下标的位置;

4、判断两颗树是否相同

https://leetcode.cn/problems/same-tree/

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
 //比较节点首先是看有没有:
 //(1)两个节点为空,那么就是相同
 //(2)一个为空,另一个不是,那么就是不相同
 //(3)两个都不为空,比较它们的val值
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    if(p==NULL && q==NULL)
        return true;
        //走到这里说明至少有一个不为空,不可能两个都是空
    if(p==NULL||q==NULL)//如果进去了,说明一个为空,另一个不为空,那么就不相等
        return false;
        //走到这里说了两个节点都不为空,开始比较val值
    if(p->val!=q->val)
        return false;

    //比较完一个节点之后还要比较它们的左右子树的节点
    return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}

//两个为空的时候才返回true、一空返回false、两个节点val不相同才返回是为了保证能遍历完整个二叉树

###思路:

比较两棵树是否相同,就要比较两棵树里面相对应节点的位置的节点数据是否相同;

而比较两个节点是否相同思路如下:

(1)对应位置的两个节点都是空节点,那么两个节点是相同的;

(2)对应位置的两个节点一个不为空,另外一个为空,那么这两个节点不相同;

(3)对应位置的两个节点都存在,但是它们的val值不相同,那么这两个节点不相同;

5、对称二叉树

. - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
 bool _isSymmetric(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 _isSymmetric(p->right,q->left)&&_isSymmetric(p->left,q->right);
 }
bool isSymmetric(struct TreeNode* root) {
    return _isSymmetric(root->left,root->right);
    //每次递归都涉及到左右子树中两个节点的比较,所以要定义一个两个形参的函数;
}

 

###思路:

首先要定义一个两个参数的函数,每次比较都是两个节点比较;第二层之后比较的就是左子树和右子树的根节点,所以递归传参的时候传的是根节点的左子树根节点和右子树根节点;

6、另一颗树的子树

. - 力扣(LeetCode)

判断另一颗树subRoot是不是树root的子树;

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
//思路:
//遍历root,有和subRoot根节点相同数值的节点就进入isSameTree比较是否相同;
//不相同不一定说明sub就不是root的子树,可能root下面的剩下未遍历的子树有和sub相同的
//继续遍历root,和sub根节点相同就进入isSameTrue进行比较,直到root未空的时候还没有返回true那么也说明root里面没有子树sub

bool isSameTree(struct TreeNode* p, struct TreeNode* q) ;

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
    if(root==NULL)
    {
        return false;
    }

    if(root->val==subRoot->val )
    {
        if(isSameTree(root,subRoot))
            return true;
    }

    bool ret3=isSubtree(root->left,subRoot);
    if(ret3)
    return ret3;
    bool ret4=isSubtree(root->right,subRoot);
    if(ret4)
    return ret4;

    return false;
}


bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    if(p==NULL && q==NULL)
        return true;
        //走到这里说明至少有一个不为空,不可能两个都是空
    if(p==NULL||q==NULL)//如果进去了,说明一个为空,另一个不为空,那么就不相等
        return false;
        //走到这里说了两个节点都不为空,开始比较val值
    if(p->val!=q->val)
        return false;

    //比较完一个节点之后还要比较它们的左右子树的节点
    return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
}

###本题思路:

首先在root里面找到和subRoot根节点val值相同的节点,再从这个节点开始,对当前节点和subRoot节点进行isSameTree的比较;

当两者相同的时候,说明subRoot是子树,返回true;

反之,继续遍历root里面的节点,root里面的节点可能有多个和subRoot根节点val值相同的节点。,每一个都要判断;直到root为NULL,说明root遍历完都没有找到和subRoot相同的子树;此时返回false;

7、构建二叉树

二叉树遍历_牛客题霸_牛客网

#include <stdio.h>
typedef struct BTreeNode
{
    char val;
    struct BTreeNode* left;
    struct BTreeNode* right;
} BTNode;

BTNode* CreatTree(char* a, int* pi);
BTNode* BuyNode(char c);
void PostOrder(BTNode* root);

int main() {
    char a[100];
    scanf("%s ",a);
    int i=0;
    BTNode* root=CreatTree(a,&i);
    PostOrder(root);
    return 0;
}

BTNode* CreatTree(char* a,int* pi)
{
    if(a[*pi]=='#')
    {
        (*pi)++;
        return NULL;
    }

    BTNode* root=BuyNode(a[(*pi)++]);
    root->left=CreatTree(a,pi);
    root->right=CreatTree(a,pi);
    
    return root;
}

BTNode* BuyNode(char c)
{
    BTNode* newnode=(BTNode*)malloc(sizeof(BTNode));
    newnode->val=c;
    newnode->left=newnode->right=NULL;

    return newnode;
}

void PostOrder(BTNode* root)
{
    if(root==NULL)
    {
        return;
    }

    PostOrder(root->left);
    printf("%c ",root->val);
    PostOrder(root->right);
}

 ###本题思路:

首先要把输入的字符串存在一个数组中,并且定义一个变量 i ,来表示在某一时刻访问数组的下标的值,当访问的数组里面的字符是‘#’的时候返回NULL,表示这个二叉树不会插入数据,并且让i++,跳过已经访问完的字符;反之,申请一个二叉树节点,再让此时访问的数组里面的字符赋值给这个节点val,同时让这个节点的左子树和右子树同样进行构建二叉树的操作,形成递归,最后访问的符号是‘#’,返回NULL,这时构建完毕,递归返回;

  • 21
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值