初阶数据结构——二叉树题目

文章目录

  • 一、单值二叉树
  • 二、检查两颗树是否相同
  • 三、另一棵树的子树
  • 四、二叉树的前序遍历
  • 五、对称二叉树


一、单值二叉树

单值二叉树

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

在这里插入图片描述
需要保证全部都相等,自然就需要左右子树都没问题。先想一个小问题,当遍历一个子树时,最终会遇到空,遇到空就要返回true,让它安全返回,不影响判断,这里也就说我们需要递归来遍历。那么现在从根开始,首先有一个判断,如果是空就返回true,跳过这个判断后,如果进行下一步?我们要让根和其他所有数字都相等,这其中最容易判断的就是根的左右子树是否相等,所以可能会写出这一个判断语句

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

这个语句还欠缺考虑。要知道,现在我们的思路是用一个根节点去和它的两个子树比较是否相等,前提是两个子树都存在。前面的判断空是在判断root,也就是判断这个根节点,并没有判断它的子树们,所以应该这样写:if(root->right && root->right->val) 。如果符合条件了,那么这就不是单值二叉树,就得返回false了,返回的false也必须让之前的递归全部都false,最终才是false。

先不想这个,回到刚才的代码,我们只写了右边,还需要写左边,也是一样,也就是两个if,都需要判断。写完这三个判断后,就得递归了。前面说到false得让整体,所有的递归都为false,并且从题目中也知道,左右子树节点的值都得等于根才行,所以当往下继续遍历的时候,需要用&&来连接

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

整体的代码

bool isUnivalTree(struct TreeNode* root) 
{if(!root) return true;if(root->left && root->val != root->left->val)return false;if(root->right && root->val != root->right->val)return false;return isUnivalTree(root->left) && isUnivalTree(root->right);
}

这道题也就结束了。题解中还有一种写法,是在判断左和右是否相等时进入递归,但这样不妥,如果从根开始,它的右子树节点的值就不相等,而程序在前面判断左子树时,如果相等,就开始了继续找左子树的递归,那么就白白浪费空间和时间了,所以现在现有的左右子树判断完再递归更好。

二、检查两颗树是否相同

相同的树

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

在这里插入图片描述
在这里插入图片描述
两棵树比较,值要相等,结构要相同。从根开始,如果两个值相等,这肯定符合要求,但是这时候不能返回true,我们还要继续往下判断,让递归进行下去,去看子树的情况,判断结构是否相同,但是不相等肯定就不行,就不是相同的树,所以可以写如果值不相等,就返回false。要让程序能够持续到最低层,来判断整体的结构是否相同,就得让其他判断条件也不能阻碍递归的前进,直到我们来到空,比如上面的例一中,2的左子树,这时候为空,如果另一棵树此时也是空,那就没问题,返回true,再往回走,去判断它的父节点的右子树;如果一个为空,一个不为空,那肯定不行,就直接返回false。而这里有一个巧妙的写法,先写两个都是空的判断,如果不是,那就要么是一空一不空,要么两个都不空,那就可以写if(p == NULL || q == NULL) 有一个为空就说明结构不相同了,因为是一空一不空。

上面这段已经写了三个判断,这三个判断就足以完成题目的要求,在最后加一个左右子树的递归即可。

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

三、另一棵树的子树

另一棵树的子树

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
在这里插入图片描述
在这里插入图片描述

既然要找子树,也就是要找到root中subRoot相同的一部分,这里就能用到刚才写的isSameTree。root有很多个子树,我们只能一个个比较,看看是否和subRoot相同,从根开始,整棵树也是root的子树,所以从root开始比较,如果root和subRoot是相同的树,那么就返回true。如果一次比较,发现不相同,程序得继续往下寻找,像例2那样,2下面还有一个0,那么从4开始比较,下面的部分就不相同,不相同,什么也不返回,继续找4的左子树和右子树进行比较。这里会想到我们要写两个式子,一个参数中有root->left,另一个是root->right,这两个只要有一个是true就说明是子树,那么程序就可以结束了,所有用或。一直往下比较,什么时候停止?如果一条路线到了空,说明这一路上的节点下的树都不和subRoot相同,那就说明这条路都不符合条件,那就返回false,返回false也不要紧,因为之前已经写了或,所以程序还会判断另一条路线是否可行,才会给出最终结果。

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) return false;if(isSameTree(root, subRoot)) return true;return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}

四、二叉树的前序遍历

前序遍历

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

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

用递归算法解。前序遍历是比较简单的,不过这里要求把遍历的结果放到一个数组中,*returnSize是数组大小,最后返回数组。虽然提示中给了节点数目范围,但用一个函数来计算给的二叉树的节点数目更适合所有树。

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

五、对称二叉树

对称二叉树

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

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

对称二叉树,根的左右子树需要比较,看是否对称,这里能够想到判断相同,不过有一定差别,根节点值同样也要相等,左子树和另一个的右子树比较,右子树和另一个的左子树比较。

另一个思路就是翻转二叉树,把左右子树翻转过来,那么就可以直接比较相同了,翻转不难,大事化小,遍历最低一层的子树,然后逐个翻转,往上走,最后完成翻转。但其实这个思路不行,如果翻转二叉树,那么翻转后原二叉树就不存在了,我们只能复制一份,然后再翻转才行,但是复制又得走一遍递归了,所以这个思路更复杂。

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

这里把两个return false的语句合并到了一起。

结束。

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

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

相关文章

Mapping温度分布验证选择数据记录仪时需要考虑的13件事

01 什么是温度分布验证? 温度分布验证是通过在规定的研究时间内测量定义区域内的多个点来确定特定温度控制环境或过程(如冷冻柜、冰箱、培养箱、稳定室、仓库或高压灭菌器)的温度分布的过程。温度分布验证的目标是确定每个测量点之间的差异&…

1.netty介绍

1.介绍 是JBOSS通过的java开源框架是异步的,基于事件驱动(点击一个按钮调用某个函数)的网络应用框架,高性能高可靠的网络IO程序基于TCP,面向客户端高并发应用/点对点大量数据持续传输的应用是NIO框架 (IO的一层层封装) TCP/IP->javaIO和网络编程–>NIO—>Netty 2.应用…

FFmepg视频解码

1 前言 上一篇文章<FFmpeg下载安装及Windows开发环境设置>介绍了FFmpeg的下载安装及环境配置&#xff0c;本文介绍最简单的FFmpeg视频解码示例。 2 视频解码过程 本文只讨论视频解码。 FFmpeg视频解码的过程比较简单&#xff0c;实际就4步&#xff1a; 打开媒体流获取…

Redis-1

Redis 理论部分 redis 速度快的原因 1、纯内存操作 2、单线程操作&#xff0c;避免了频繁的上下文切换和资源争用问题&#xff0c;多线程需要占用更多的 CPU 资源 3、采用了非阻塞 I/O 多路复用机制 4、提供了非常高效的数据结构&#xff0c;例如双向链表、压缩页表和跳跃…

idea模块的pom.xml被划横线,不识别的解决办法

目录 问题&#xff1a; 解决办法&#xff1a; 1.打开设置 2. 取消勾选 3.点击确认 4.解决 问题提出&#xff1a; 写shi山的过程中&#xff0c;给模块取错名字了&#xff0c;改名的时候不知道点到了什么&#xff0c;一个模块的pom.xml变成灰色了&#xff0…

【Spring Cloud 四】Ribbon负载均衡

Ribbon负载均衡 系列文章目录背景一、什么是Ribbon二、为什么要有Ribbon三、使用Ribbon进行负载均衡服务提供者A代码pom文件yml配置文件启动类controller 服务提供者Bpom文件yml配置文件启动类controller 服务消费者pom文件yml文件启动类controller 运行测试 四、Ribbon的负载均…

Vue没有node_modules怎么办

npm install 一下 然后再npm run serve 就可以运行了

isp调试工具环境搭建及其介绍!

一、isp调试环境搭建&#xff1a; 后期调试isp&#xff0c;是在rv1126提供的RKISP2.x Tuner工具上进行调试&#xff0c;所以我们大前提必须要把这个环境和一些操作先搞熟悉来&#xff0c;后面有一些专用术语&#xff0c;我们遇到了再去看&#xff0c;现在专门看一些专用术语&am…

冠达管理:光伏巨头大反弹!业绩环比提升+低市盈率+超跌股仅14只

今年以来&#xff0c;部分公司得益于职业景气量提高、上游成本下滑、财物处置等原因&#xff0c;连续两个季度净利润继续改进。 光伏巨子成绩环比大幅增加&#xff0c;股价底部大涨 8月3日&#xff0c;光伏龙头隆基绿能股价大涨6.05%&#xff0c;全天成交额到达89.85亿元&…

Stable Diffusion AI绘画初学者指南【概述、云端环境搭建】

概述、云端环境搭建 Stable Diffusion 是什么、能干啥&#xff1f; 是一种基于深度学习的图像处理技术&#xff0c;可以生成高质量的图像。它可以在不需要真实图像的情况下&#xff0c;通过文字描述来生成逼真的图像。 可以对图像进行修复、超分辨率转换&#xff0c;将低分辨…

【BASH】回顾与知识点梳理(一)

【BASH】回顾与知识点梳理 一 前言一. 认识与学习 BASH1.1 硬件、核心与 Shell1.2 为何要学文字接口的 shell&#xff1f;1.3 系统的合法 shell 与 /etc/shells 功能1.4 Bash shell 的功能1.5 查询指令是否为 Bash shell 的内建命令&#xff1a; type1.6 指令的下达与快速编辑按…

[openCV]基于拟合中线的智能车巡线方案V4V5

V4: import cv2 as cv import os import numpy as npimport time# 遍历文件夹函数 def getFileList(dir, Filelist, extNone):"""获取文件夹及其子文件夹中文件列表输入 dir&#xff1a;文件夹根目录输入 ext: 扩展名返回&#xff1a; 文件路径列表""…

Cpp9 — map和set

map和set STL分为序列式容器&#xff08;vector、list、deque&#xff09;和关联式容器&#xff08;map、set&#xff09; 序列式容器&#xff1a;数据与数据之间没有很强的联系。&#xff08;各个数据之间没什么关联&#xff09;。底层为线性序列的数据结构&#xff0c;里面…

C语言每日一题:13《数据结构》环形链表。

题目链接&#xff1a; 一.环形链表运动基础。 使用快慢指针利用相对移动的思想&#xff1a; 1.第一种情况&#xff1a; 1,令快指针&#xff08;fast&#xff09;速度为2. 2.慢指针&#xff08;slow&#xff09;速度为1. 3.以慢指针进入环中开始。 4。假设slow刚刚进入环中fast…

如何把pdf转成cad版本?这种转换方法非常简单

将PDF转换成CAD格式的优势在于&#xff0c;CAD格式通常是用于工程设计和绘图的标准格式。这种格式的文件可以在计算机上进行编辑和修改&#xff0c;而不需要纸质副本。此外&#xff0c;CAD文件通常可以与其他CAD软件进行交互&#xff0c;从而使得工程设计和绘图过程更加高效和精…

CSS 滚动条

一、滚动条样式属性 ::-webkit-scrollbar {width: 6px; /* 竖向滚动条宽度 */height: 6px; /* 横向滚动条高度 */ }::-webkit-scrollbar-thumb {border-radius: 10px; /* 滚动条样式 */-webkit-box-shadow: inset 0 0 3px red; /* 内阴影 */background-color: blue; /* 滚动条…

卷积神经网络

目录 注意&#xff1a;有参数计算的才叫层 1.应用 1.1分类和检索 1.2超分辨率重构 1.3医学任务 1.4无人驾驶 1.5人脸识别 2.卷积 2.1卷积神经网络和传统网络的区别 2.2整体框架 2.3理解卷积&#xff08;重点&#xff09; 2.4为何要进行多层卷积 2.5卷积核的参数 2.6…

【2023 华数杯全国大学生数学建模竞赛】 B题 不透明制品最优配色方案设计 详细建模方案解析及参考文献

【2023 华数杯全国大学生数学建模竞赛】 B题 不透明制品最优配色方案设计 详细建模方案解析及参考文献 1 题目 B 题 不透明制品最优配色方案设计 日常生活中五彩缤纷的不透明有色制品是由着色剂染色而成。因此&#xff0c;不透明制品的配色对其外观美观度和市场竞争力起着重要…

时间复杂度和空间复杂度

目录 一. 时间复杂度 有循环的时间复杂度例子&#xff1a; 1. 求冒泡排序的时间复杂度&#xff1f;O(n^2) 2. 求二分查找的时间复杂度&#xff1f;O(logn) 3. 求斐波那契数的时间复杂度&#xff1f;O(n) ​编辑 递归的时间复杂度例子&#xff1a; 1. 递归求阶乘&#…

Vue2(初识vue)

目录 一&#xff0c;Vue2简介1.1&#xff0c;什么是vue1.2&#xff0c;初始vue1.3&#xff0c;搭建vue环境1.4&#xff0c;第一个hello world 二&#xff0c;基础知识2.1 指令2.2-1 指令v-text2.2-2 指令v-html2.2-3 指令v-if2.2-4 指令v-else2.2-5 指令v-show2.2-6 v-if指令与…