LeetCode-二叉树

1、判断单值二叉树

. - 力扣(LeetCode)

cpp 复制代码
/**
 * 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)

cpp 复制代码
/**
 * 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)

cpp 复制代码
/**
 * 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/

cpp 复制代码
/**
 * 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)

cpp 复制代码
/**
 * 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的子树;

cpp 复制代码
/**
 * 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、构建二叉树

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

cpp 复制代码
#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,这时构建完毕,递归返回;

相关推荐
唐叔在学习2 分钟前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA21 分钟前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo23 分钟前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc30 分钟前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
姚先生9740 分钟前
LeetCode 54. 螺旋矩阵 (C++实现)
c++·leetcode·矩阵
测试杂货铺2 小时前
如何用postman做接口自动化测试及完美的可视化报告?
自动化测试·软件测试·测试工具·职场和发展·jenkins·压力测试·postman
游是水里的游2 小时前
【算法day20】回溯:子集与全排列问题
算法
yoyobravery2 小时前
c语言大一期末复习
c语言·开发语言·算法
Jiude2 小时前
算法题题解记录——双变量问题的 “枚举右,维护左”
python·算法·面试
被AI抢饭碗的人2 小时前
算法题(13):异或变换
算法