【数据结构】二叉树oj题

在处理oj题之前我们需要先处理一下之前遗留的问题

在二叉树中寻找为x的节点

BTNode* BinaryTreeFind(BTNode* root, int x)
{if (root == NULL)return NULL;if (root->data == x)return root;BTNode* ret1 = BinaryTreeFind(root->left, x);BTNode* ret2 = BinaryTreeFind(root->right, x);if (ret1)return ret1;if (ret2)return ret2;return NULL;}

递归图
在这里插入图片描述
分别用ret1,ret2指针记录左子树,右子树的返回值,如果在左子树找到就会返回一个地址,用ret1记录指针,使得ret1不为空,此时会递归返回上一层,在上一层中进入if(ret1)条件判断语句中,返回节点为x的地址到上一层,一直到整棵树的根节点.同理ret2不为空也一样.
在这里插入图片描述

#单值二叉树

题目描述
在这里插入图片描述
代码

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

递归图
在这里插入图片描述

当根和左右子树都相等的时候,就会一直递归左右子树,左右子树分别做根节点,和他的左右子树判断是否相等,当递归到叶子结点的左树,右树时,两个都会返回1,右侧中间的1,的左子树为空,右子树为1,左子树为空将会返回1,右子树为根,他的左右子树为空,返回1,树的根节点的左右子树返回两个1相与得到1,如此就可以判断得到结果,具体见上面的递归图.
#对称二叉树
题目描述
在这里插入图片描述
代码

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

在这里插入图片描述
在这里插入图片描述

#二叉树的前序遍历
在这里插入图片描述
代码

 int BinaryTreeSize(struct TreeNode* root)
{return root == NULL ? 0 : BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;}
void aapreorderTraversal(struct TreeNode*root,int*a,int i)
{if(root==NULL)return ;a[i++]=root->val;aapreorderTraversal(root->left,a,i);aapreorderTraversal(root->right,a,i);
}int* preorderTraversal(struct TreeNode* root, int* returnSize) {*returnSize=BinaryTreeSize(root);int*a=(int*)malloc(*returnSize*sizeof(int));int i=0;aapreorderTraversal(root,a,i);return a;
}

注意上述代码有些问题,我先来解释一下代码,然后在解决上述问题,
之前我们写过前序遍历,但是这个题不同的是需要将前序遍历的结果放到一个数组中并且返回这个数组,首先我们解决的问题是二叉树结点的个数问题,因为要创建同大小的数组,这里我们就需要使用求二叉树结点个数的函数,返回的结点个数用returnsize接收,
在这里插入图片描述
并且该数组需要自己创建,
在这里插入图片描述
如果在这个函数里面采用前序遍历的话,每次递归都会malloc,所以我们使用另一个函数来递归前序遍历,
在这里插入图片描述
在这里插入图片描述
给递归前序遍历函数传的参数分别有要遍历二叉树的根的地址,malloc来的数组首地址,以及数组的下标,具体的前序遍历在二叉树那一篇文章中有详细的解释,现在讲一下存在的问题
在这里插入图片描述
在这里插入图片描述
当进入数据为2的栈帧此时的i还是1,就会覆盖掉数据为1的栈帧写入a[1]=1;
现在的a[1]=2;由于在二叉树结点个数中已经知道有三个结点,于是就会将
(a+2)里面的随机值打印出来,具体解决办法,传下标的地址过去,用指针接收.
代码

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

#中序遍历
#后序遍历
这两个只需要修改位置即可
在这里插入图片描述
#另一颗子树
题目描述
在这里插入图片描述
代码实现

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

这里用到了相同的树的函数

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

递归二叉树,分别以当前结点做根,与subRoot做比较,如果不同,就递归左右子树,如果左右子树中有与subroot为根的树相同的子树,就返回1,当根相同时,会调用函数isSameTree(struct TreeNode* p, struct TreeNode* q)比较左子树和右子树是否相同,如果刚开始root==NULL,肯定subroot不为子树返回false.建议大家画一下递归图会好理解很多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/221537.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【前沿技术了解】web图形Canvas、svg、WebGL、数据可视化引擎的技术选型

目录 Canvas:HTML5新增 Canvas标签(画布) 渲染上下文canvas.getContext(contextType[, contextAttributes]) 上下文类型(contextType) 上下文属性 (contextAttributes) 示例 动画 setInterval(function, delay)…

组装自己的稳定扩散模型

在本文中,我们将利用 Hugging Face Diffusers 库的组件实现自己的稳定扩散模型,可以像 diffuser.diffuse() 一样简单地生成图像。 在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编…

Portraiture全新4.1.2版本升级更新

关于PS修图插件,相信大家都有安装过使用过,而且还不止安装了一款,比如最为经典的DR5.0人像精修插件,Retouch4me11合1插件,Portraiture磨皮插件,这些都是人像精修插件中的领跑者。其中 Portraiture 刚刚升级…

内网隧道学习

默认密码:hongrisec2019 一.环境搭建 网卡学习 一个网卡一个分段,想象成一个管道 192.168.52一段 192.168.150一段 仅主机模式保证不予外界连通,保证恶意操作不会跑到真实机之上 52段是内部通信,150段属于服务器(…

C语言学习笔记之函数篇

与数学意义上的函数不同,C语言中的函数又称为过程,接口,具有极其重要的作用。教科书上将其定义为:程序中的子程序。 在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, me…

FFmpeg零基础学习(二)——视频文件信息获取

目录 前言正文一、获取宽高信息1、核心代码2、AVFormatContext3、avformat_alloc_context4、avformat_open_input5、avformat_find_stream_info6、av_dump_format7、av_find_best_stream End、遇到的问题1、Qt Debug模式avformat_alloc_context 无法分配对象,而Rele…

【Spring】Spring是什么?

文章目录 前言什么是Spring什么是容器什么是 IoC传统程序开发控制反转式程序开发理解Spring IoCDI Spring帮助网站 前言 前面我们学习了 servlet 的相关知识,但是呢?使用 servlet 进行网站的开发步骤还是比较麻烦的,而我们本身程序员就属于是…

广度优先遍历与最短路径

广度优先遍历从某个顶点 v 出发,首先访问这个结点,并将其标记为已访问过,然后顺序访问结点v的所有未被访问的邻接点 {vi,..,vj} ,并将其标记为已访问过,然后将 {vi,...,vj} 中的每一个节点重复节点v的访问方法&#xf…

Runloop解析

RunLoop 前言 ​ 本文介绍RunLoop的概念,并使用swift和Objective-C来描述RunLoop机制。 简介 ​ RunLoop——运行循环(死循环),它提供了一个事件循环机制在程序运行过程中处理各种事件,例如用户交互、网络请求、定…

HT97226 免输出电容立体声耳机放大器的应用与曲线

HT97226应用: ・耳机 ・多媒体音频接口 ・机顶盒 ・ 蓝光/DVD播放器 ・LCD电视 ・音频消费电子产品 HT97226应用图于曲线: HT97226是一款差分输入/单端输入、可直接输出驱动的耳机放大器。5V供…

网络渗透测试(认识)

ARP协议 逻辑地址变成物理地址 32bit的IP地址变换成48bit的mac地址 ARP两个字节(0x0806) ARP解析协议 每一个主机都有ARP高速缓存,此缓存中记录了最近一段时间的内其他IP地址与其MAC地址的对应关系 如果本机想与某台主机通信,首先…

Azure Machine Learning - 创建Azure AI搜索服务

目录 准备工作查找 Azure AI 搜索产品/服务选择订阅设置资源组为服务命名选择区域选择层创建服务配置身份验证扩展服务何时添加第二个服务将多个服务添加到订阅 Azure AI 搜索是用于将全文搜索体验添加到自定义应用的 Azure 资源,本文介绍如何创建Azure AI搜索服务 …