【数据结构和算法】二叉树基础oj练习(1)

bool isUnivalTree(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.检查两颗树是否相同


–oj链接

在这里插入图片描述

题解:

判断两棵二叉树是否相同,也可以将其分解为子问题:

1.比较两棵树的根是否相同。

2.比较两根的左子树是否相同。

3.比较两根的右子树是否相同。

代码:

//判断两棵二叉树是否相同

bool isSameTree(BTNode* p, BTNode* q)

{

if (p == NULL&&q == NULL)//两棵树均为空,则相同

return true;

if (p == NULL || q == NULL)//两棵树中只有一棵树为空,则不相同

return false;

if (p->data != q->data)//两棵树根的值不同,则不相同

return false;

return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);//两棵树的左子树相同并且右子树相同,则这两棵树相同

}

3.对称二叉树


–oj链接

在这里插入图片描述

题解:

要判断某二叉树是否是对称二叉树,则判断其根结点的左子树和右子树是否是镜像对称即可。若在遍历过程中发现镜像对称的某两个结点值不同,则无需继续遍历。

在这里插入图片描述

代码:

//判断镜像位置是否相等

bool travel(BTNode* root1, BTNode* root2)

{

if (root1 == NULL&&root2 == NULL)//红蓝轨迹同时遍历到NULL,函数返回

return true;

if (root1 == NULL || root2== NULL)//红蓝指针中,一个为NULL,另一个不为NULL,即镜像不相等

return false;

if (root1->val!= root2->val)//红蓝指针指向的结点值不同,即镜像不相等

return false;

//子问题:左子树遍历顺序:先左后右,右子树遍历顺序:先右后左。若两次遍历均成功,则是对称二叉树

return travel(root1->left, root2->right) && travel(root1->right, root2->left);

}

//对称二叉树

bool isSymmetric(BTNode* root)

{

if (root == NULL)//空树是对称二叉树

return true;

return travel(root->left, root->right);//判断镜像位置是否相等

}

4.另一颗树的子树


–oj链接

在这里插入图片描述

题解:

思路:

一个树是另一个树的子树则要么这两个树相等,要么这个树是左树的子树,要么这个树的右树的子树。

用两层递归来实现:

isSameTree函数用于递归检查需要判断的树对应结点是否相同(即判断相同二叉树);

isSubtree函数则用于判断subRoot 是否为root的子树;

代码:

/**

  • Definition for a binary tree node.

  • struct TreeNode {

  • int val;
    
  • struct TreeNode *left;
    
  • struct TreeNode *right;
    
  • };

*/

//检验这两棵树是否相同

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

if(pNULL&&qNULL)

return true;

if(pNULL||qNULL)

return false;

if(p->val!=q->val)

return false;

return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);

}

//判断subRoot 是否为root的子树

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

if(root==NULL)//空树,不可能是与subRoot相同(subRoot非空)

return false;

if(isSameTree(root,subRoot))//以root和subRoot为根,开始比较两棵树是否相同

return true;

//判断root的左孩子和右孩子中是否有某一棵子树与subRoot相同

return isSubtree(root->left,subRoot)||

isSubtree(root->right,subRoot);

}

5.二叉树的构建及遍历


–oj链接

在这里插入图片描述

题解:

根据前序遍历所得到的字符串,我们可以很容易地将其对应的二叉树画出来:

在这里插入图片描述

我们可以依次从字符串读取字符:

1.若该字符不是#,则我们先构建该值的结点,然后递归构建其左子树和右子树。

2.若该字符是#,则说明该位置之下不能再构建结点了,返回即可。

构建完树后,使用中序遍历打印二叉树的数据即可。

#include <stdio.h>

#include <stdlib.h>

typedef struct TreeNode

{

struct TreeNode* left;

struct TreeNode* right;

char data;

}TreeNode;

//创建树

TreeNode* CreateTree(char* str, int* pi)

{

if(str[*pi] == ‘#’)//

{

(*pi)++;

return NULL;

}

//不是NULL,构建结点

TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));

root->data = str[*pi];

(*pi)++;

//递归构建左子树

root->left = CreateTree(str, pi);

//递归构建右子树

root->right = CreateTree(str, pi);

return root;

}

//中序遍历

void Inorder(TreeNode* root)

{

if(root == NULL)

return;

Inorder(root->left);

printf("%c ", root->data);

Inorder(root->right);

}

int main()

{

char str[100];

scanf(“%s”, str);

int i = 0;

TreeNode* root = CreateTree(str, &i);

Inorder(root);

return 0;

}

6.二叉树的前序遍历


–oj链接

在这里插入图片描述

题解

前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前

思路:

1.首先计算二叉树中结点的个数,便于确定动态开辟的数组的大小。

2.遍历二叉树,将遍历结果存储到数组中。

3.返回数组。

代码:

/**

  • 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 TreeSize(struct TreeNode* root)//求树的结点个数

{

if(root==NULL)

return 0;

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

}

void _preorderTraversal(struct TreeNode* root,int *arr,int *pi)//将树中结点的值放入数组

{

if(root==NULL)

{

return;

}

//前序遍历

arr[(*pi)++]=root->val;//先将根结点的值放入数组

_preorderTraversal(root->left,arr,pi);//再将左子树中结点的值放入数组

_preorderTraversal(root->right,arr,pi);//最后将右子树中结点的值放入数组

}

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

{

*returnSize=TreeSize(root);

int arr=malloc(sizeof(int) *returnSize);

int i=0;

_preorderTraversal(root,arr,&i);

return arr;

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

写在最后

还有一份JAVA核心知识点整理(PDF):JVM,JAVA集合,JAVA多线程并发,JAVA基础,Spring原理,微服务,Netty与RPC,网络,日志,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算…

image

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
注Java获取)**

img

写在最后

还有一份JAVA核心知识点整理(PDF):JVM,JAVA集合,JAVA多线程并发,JAVA基础,Spring原理,微服务,Netty与RPC,网络,日志,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算…

[外链图片转存中…(img-MEZyN3l2-1713549977840)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值