二叉树的OJ练习题

1.单值二叉树

描述:如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时,才返回 true;否则返回 false

链接:965. 单值二叉树 - 力扣(LeetCode)

思路:比较每个父亲节点与左右非空孩子节点的值。

bool isUnivalTree(struct TreeNode* root){

    if(root==NULL)

    {

        return true;//该节点不存在,无需比较

    }

    //左边存在

    if(root->left&&root->left->val!=root->val)

    {

        return false;

    }

    //右边存在

    if(root->right&&root->right->val!=root->val)

    {

        return false;

    }

    return isUnivalTree(root->left)&&isUnivalTree(root->right);

//遍历左边所有节点和右边所有节点 ,返回左右节点相与的结果

2.二叉树的最大深度

描述:求二叉树的深度

链接:104. 二叉树的最大深度 - 力扣(LeetCode)

思路:比较每个根节点(递归的所有节点都是根)的左右高度差,高的那个加上根节点长度1。

 代码:

int maxDepth(struct TreeNode* root){

    if(root==NULL)

    {

        return 0;

    }

    int left=maxDepth(root->left);//遍历左边的节点

    int right=maxDepth(root->right);//遍历右边的节点

    return left>right?left+1:right+1;//左右边高的那个加上根节点(高度为1)

}

最后一次比较就是左边的高度与右边的高度,最后长的那个加上根节点高度1.

 3.翻转二叉树

描述:给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

 链接:226. 翻转二叉树 - 力扣(LeetCode)

思路:交换每个父亲节点的左右孩子节点位置

代码:

//因为需要返回节点,所以用子函数去递归交换

void _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);//右子树的每个节点左右孩子交换

}

struct TreeNode* invertTree(struct TreeNode* root){

    if(root==NULL)

    {

        return NULL;

    }

    _invertTree(root);

    return root;

}

4.相同的树 

描述:给定两颗树,判断他们的数据域是否相同

链接:100. 相同的树 - 力扣(LeetCode)

思路:比较两棵树(p和q)所有相同位置的数据。节点存在有三种情况,1.p和q的节点都不存在,都是NULL,相同。2.p和q只有一个存在节点,两树必不相同,3.p和q的节点都存在,此时比较数据。

代码:

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

    //两个都为空 true  

    if(p==NULL&&q==NULL)

    {

        return true;

    }

    //其中一个为空 false

    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);

}

5.二叉树的前序遍历 

描述:给你二叉树的根节点 root ,返回它节点值的前序遍历。前序遍历的数据存储到malloc出来的数组中,最后返回数组。

链接:144. 二叉树的前序遍历 - 力扣(LeetCode)

思路:求树的节点个数为自定义数组开辟空间,递归实现前序遍历

代码:

//得到树的节点个数,开辟数组空间

int TreeSize(struct TreeNode* root)

 {

     if(root==NULL)

     {

         return 0;

     }

     return TreeSize(root->left)+TreeSize(root->right)+1;

 }

//子函数递归

void _preorderTraversal(int*a, struct TreeNode* root,int* pi)//pi为数组递归下标位置

{

    if(root==NULL)

    {

        return;

    }

    a[(*pi)++]=root->val;

     _preorderTraversal(a,root->left,pi);

     _preorderTraversal(a,root->right,pi);

}

int* preorderTraversal(struct TreeNode* root, int* returnSize){

    int size=TreeSize(root);

    int* a=(int*)malloc(sizeof(int)*size);

    int i=0;

    //返回值不容易写递归条件 写一个子函数

    _preorderTraversal(a,root,&i);

    *returnSize=size;

    return a;

}

6.判断一颗二叉树是否是平衡二叉树

描述:一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

链接:110. 平衡二叉树 - 力扣(LeetCode)

思路:比较每个节点的左右字树高度差

代码:

//求高度

int HighTree(struct TreeNode* root)

{

    if(root==NULL)

    {

        return 0;

    }

    int left=HighTree(root->left);

    int right=HighTree(root->right);//左右高的那个返回

    return left>right?left+1:right+1;

}

bool isBalanced(struct TreeNode* root){

    if(root==NULL)

    {

        return true;

    }

    //思路:求左右子树的高度,比较高度的绝对值

    int left=HighTree(root->left);

    int right=HighTree(root->right);

    int dis=abs(left-right);

    if(dis>1)

    {

        return false;

    }

    return isBalanced(root->left)&&isBalanced(root->right);

}

7.另一颗树的字树 

描述:给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false。

链接:572. 另一棵树的子树 - 力扣(LeetCode)

思路:root的每一棵子树与subRoot比较 

 

代码:

//比较函数

bool issametree(struct TreeNode* root, struct TreeNode* subRoot)

 {

    if(root==NULL&&subRoot==NULL)

    {

        return true;

    }

    //2.其中之一为空

    if(root==NULL||subRoot==NULL)

    {

        return false;

    }

    

    //3.都不为空,比较值

    if(root->val!=subRoot->val)

    {

        return false;

    }

    return issametree(root->left,subRoot->left)&&issametree(root->right,subRoot->right);

 }

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){

    //思路:root的每一棵子树都与subRoot比较

     if(root==NULL)

     {

         return false;

     }

     if(issametree(root,subRoot))

     {

         return true;

     }

    return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);//root左边或者右边相同即可

}

8.对称二叉树

描述:给你一个二叉树的根节点 root , 检查它是否轴对称。

链接:101. 对称二叉树 - 力扣(LeetCode)

思路:判断根节点的左子树与右子树是否满足镜像对称,镜像对称:左子树的遍历方式和右子树的遍历方式是相反的。

 代码:

bool _isSymmetric(struct TreeNode* r,struct TreeNode* l)

{

   if(l==NULL&&r==NULL)

    {

        return true;

    }

    if(l==NULL||r==NULL)

    {

        return false;

    }

    if(l->val!=r->val)

    {

        return false;

    }

    return _isSymmetric(r->left,l->right)&&_isSymmetric(r->right,l->left);//1.左树l左边走,右树r右边走。2.左树l右边走,右树r左边走

}

bool isSymmetric(struct TreeNode* root){

    if(root==NULL)

    {

        return true;

    }

    return _isSymmetric(root->left,root->right);//子函数比较左右子树是否相同

}

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值