二叉树经典OJ题——【数据结构】

news2024/9/25 13:19:25

W...Y的主页 😊

代码仓库分享 💕 


今天我们来进行二叉树的OJ练习,就是利用二叉树的前序、中序、后续以及晨序遍历的特性进行OJ训练。话不多说,来看我们的第一道题。

【leetcode 965.单值二叉树】

OJ链接 

如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。

只有给定的树是单值二叉树时,才返回 true;否则返回 false

示例 1:

输入:[1,1,1,1,1,null,1]
输出:true

示例 2:

输入:[2,2,2,5,2]
输出:false

题目函数接口:

root:二叉树的根节点指针。 返回值:bool类型(真 true 假 false)


给定一个二叉树,我们需要判断树中val的值是不是相同的。我们的思路就是将其全部遍历一遍,如果在遍历过程中发现其中有一个数与其余数不同即可停止,返回false,反之返回true

强调一下:数与数之间是有传递性的,所以我们不需要将其遍历时先创建一个变量将val值进行标记。a = b,b=c,那么a=c。

代码实现:

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

当我们root等于空时,满足题中要求,所以要返回true。当root的左子树不为空并且左子树的val值,不等于其父节点val值则返回false,同理root的右子树不为空且右子树的val值不等于其父节点val值则返回flase。最后我们进行一个递归遍历,将树中的所有节点全部遍历一遍即可,如果有一个返回false,则最终返回false。左子树与右子树必须全部为true才真正为true

这个函数的原理其实就是前序遍历的变形。

我们简单画一张递归分析图:

【leetcode 100.相同的树】 

OJ链接

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:

输入:p = [1,2,3], q = [1,2,3]
输出:true

示例 2:

输入:p = [1,2], q = [1,null,2]
输出:false

示例 3:

输入:p = [1,2,1], q = [1,1,2]
输出:false

题目函数接口:

p:一棵树的根节点指针。q:另一颗树的根节点指针


这道题给予我们两个树,让我们检查两颗树是否相同。

我们就是模仿遍历。当我们遍历一棵树的左子树时,另一颗树也遍历其左子树。右子树同理即可。(如同模仿者一样同步进行)

大概思路已经确定,下面就是细节了。

当两棵树的节点都为NULL,我们返回true。当两棵树的节点一个为空,另一个不为空,我们返回false。当两个节点的val值不相同时,我们也返回空。

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

和上面的题递归类型基本相同,先递归左树再递归右树,只有两个树递归完成后返回值都为true才为true。

【leetcode 101.对称二叉树】

OJ链接 

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

示例 1:

输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:

输入:root = [1,2,2,null,3,null,3]
输出:false

题目函数接口:

root:二叉树的根节点。bool:bool类型(真 true 假 false)


这道题与leetcode 100.相同的树做法非常相似,就是一道变形题。它将两颗树变成一棵树,然后考察这棵树是否对称。

我们可以继续依照上题,一棵树看作两棵树,但是这两个树的根节点都为root。然后进行遍历判断。因为是判断树是否对称,所以两个指针应该一个遍历左树,一个遍历右数,然后检查每个节点的val是否相等即可。

代码演示:

bool checkroot(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 checkroot(p->left, q->right)&&checkroot(p->right, q->left);
}
bool isSymmetric(struct TreeNode* root){
   return checkroot(root, root);
}

注意:这道题的return checkroot(p->left, q->right)&&checkroot(p->right, q->left);是左树与右树进行比较,与上一题的return值不同。

为了更好的理解,递归展开图:

【leetcode 572. 另一颗子树】

OJ链接 

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

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

示例 1:

输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true

示例 2:

输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false

题目函数接口:

root: 大树的根节点。 suboot:小树的根节点。


这道题我们将大树中可以分解成一颗颗与小树结构相同的树,然后遍历比较即可。依旧是leetcode100.相同的树的变形。

代码展示:

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

 【leetcode 104.二叉树的最大深度】

OJ链接

给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:3

示例 2:

输入:root = [1,null,2]
输出:2

要想找到二叉树的最大深度,我们必须用深度优先遍历,前中后序都可以。将树进行遍历,每进入一颗子树就进行计数+1。

代码演示:

int maxDepth(struct TreeNode* root){
    if(root == NULL)
    {
        return 0;
    }
    int val1 = 0, val2 = 0;
    val1 =  maxDepth(root->left);
    val2 = maxDepth(root->right);
    

    return val1 >= val2 ? val1+1 : val2+1;
}

注意:我们必须再函数中创建临时变量用来接收递归函数每次的返回值。

遍历左树与右数,谁的值大(树的深度深)就返回谁。

【leetcode 树的前中后遍历】——这是三道题

前序:OJ链接

中序:OJ链接

后序: OJ链接

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

示例 1:

输入:root = [1,null,2,3]
输出:[1,2,3]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

输入:root = [1,2]
输出:[1,2]

示例 5:

输入:root = [1,null,2]
输出:[1,2]

题目函数接口:

root:是目标二叉树的根。returnSize:因为函数只能返回一个值,所以这个参数是动态开辟的数组长度。 int*:返回数组的地址。


这里的前序遍历不仅仅只是前序遍历,而是将前序遍历的数全部放入数组中去。

所以我们必须开辟动态数组将其数放入。那么我们首先的任务就是得求出二叉树中的所有节点个数。

我们创建一个函数,然后进行前序遍历计数,返回一棵树的节点个数。

int TreeSize(struct TreeNode* root)
 {
     return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
 }

然后我们动态开辟空间,然后遍历树将树中的每个节点的val值放入数组中。创建一个int变量记录数组角标,每放一个变量++。最后返回数组地址即可。

代码演示:

void preorder(struct TreeNode* root, int* a, int* i)
 {
     if(root == NULL)
     {
         return;
     }
     a[(*i)++] = root->val;
     preorder(root->left, a, i);
     preorder(root->right, a, i);
 }
int* preorderTraversal(struct TreeNode* root, int* returnSize){
    int n = TreeSize(root);
    int* a = (int*)malloc(sizeof(int)*n);

    int j = 0;
    preorder(root, a, &j);

    *returnSize = n;
    return a;
}

注意:我们创建的变量进行调用时应该传入地址,而不是单纯的值。因为如果传入对应的值,在每次调用函数时这个值不会累记,在调用函数结束后i会跟着销毁。


中序与后序与前序基本相同,只有三行代码调整了一下顺序。因为遍历顺序不同。

下面是代码展示:

中序:

int Treesize(struct TreeNode* root)
 {
     return root == NULL ? 0 :Treesize(root->left) + Treesize(root->right) + 1;
 }
 void InOrder(int* a, struct TreeNode* root, int* j)
 {
     if(root == NULL)
     {
         return;
     }
     InOrder(a, root->left, j);
     a[(*j)++] = root->val;
     InOrder(a, root->right, j);
    
 }
int* inorderTraversal(struct TreeNode* root, int* returnSize){
    int size = Treesize(root);
    int* a = (int*)malloc(sizeof(int) * size);
    int j = 0; 
    InOrder(a, root, &j);
    *returnSize = size;
    return a;
}

后序:

int Treesize(struct TreeNode* root)
 {
     return root == NULL ? 0 :Treesize(root->left) + Treesize(root->right) + 1;
 }
 void PostOrder(int* a, struct TreeNode* root, int* j)
 {
     if(root == NULL)
     {
         return;
     }
     PostOrder(a, root->left, j);
     PostOrder(a, root->right, j);
    a[(*j)++] = root->val;
 }
int* postorderTraversal(struct TreeNode* root, int* returnSize){
    int size = Treesize(root);
    int* a = (int*)malloc(sizeof(int) * size);
    int j = 0; 
    PostOrder(a, root, &j);
    *returnSize = size;
    return a;
}

【牛客网 KY11 二叉树遍历】

OJ链接 

描述:

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

输入描述:

输入包括1行字符串,长度不超过100。

输出描述:

可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。 每个输出结果占一行。

示例1

输入:

abc##de#g##f###

输出:

c b e g d f a 

这道题不是接口题,所以我们就要自己动手创建二叉树。从main函数走起。

首先我们得了解题意,有一串字符数组是按照二叉树前序遍历出来的。我们就要将其建立成正常二叉树,然后再使用中序遍历将其一一打印出来即可。

注意:’#‘代表的是空格,也就是NULL。

我们使用示例1先来推测出二叉树的基本样子:

其实只要给我们前序遍历的树,我们就可以推测出二叉树的样子。

然后就是我们先创建出二叉树的结构体:

typedef struct BinaryTreeNode
{
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
	int val;
}BTNode;

就应该写主函数了,先创建一个数组进行存储写入数据,然后就得创建一个可以将数组变成二叉树的函数CreatTree,参数我们传入字符数组和角标i,调用函数一定要传入i的指针!!

如果遇到’#‘就直接返回NULL,如果不是NULL就malloc一个节点进行存储,然后让i++。继续递归出左子树与右子树。

最后再创建一个可以中序遍历的树调用打印即可。

完整代码如下:

#include <stdio.h>
#include<stdlib.h>
typedef struct BinaryTreeNode
{
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
	int val;
}BTNode;

BTNode* CreateTree(char* str, int *pi)
{
    if(str[*pi] == '#')
    {
        ++(*pi);
        return NULL;
    }
    BTNode* root = (BTNode*)malloc(sizeof(BTNode));
    root->val = str[*pi];
    (*pi)++;
    root->left = CreateTree(str,pi);
    root->right = CreateTree(str, pi);

    return root;
}
void Inorder(BTNode* root)
{
    if(root == NULL)
    {
        return;
    }
    Inorder(root->left);
    printf("%c ", root->val);
    Inorder(root->right);
}
int main() {
    char str[100];
    scanf("%s", str);
    int i = 0;
    BTNode* root = CreateTree(str, &i);
    Inorder(root);
    return 0;
}

以上就是经典二叉树的OJ习题分享,希望对大家有所帮助。

觉得帮助到了你,就给博主一个三连关注吧!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript基础知识12——运算符:算数运算符,比较运算符

哈喽&#xff0c;大家好&#xff0c;我是雷工。 以下为JavaScript基础知识学习笔记。 一、算数运算符 1、算术运算符&#xff1a;即进行数学计算的符号。 2、有哪些算数运算符&#xff1a; &#xff1a;加法 -&#xff1a;减法 *&#xff1a;乘法 /:除法 %:取余&#xff08;…

湖南衡阳3D扫描在生物仿真研究的应用高精度三维扫描螃蟹-CASAIM中科广电

生物仿真研究与应用一直是科研及工艺品的热门方向&#xff0c;很多设计脱胎于生物本身&#xff0c;传统方式又大多只能以画师手绘为主&#xff0c;做到“纤毫毕现”极其困难&#xff0c;故而才有了“齐白石的虾”、“徐悲鸿的马”等出圈的艺术家的画作&#xff0c;对于某种生物…

云原生的简单理解

一、何谓云原生&#xff1f; 一种构建和运行应用软件的方法 应用程序从设计之初即考虑到云的环境&#xff0c;原生为云而设计&#xff0c;在云上以最佳姿势运行&#xff0c;充分利用和发挥云平台的弹性分布式优势。 二、包括以下四个要素 采用容器化部署&#xff1a;实现云平…

ASfP: 增强AOSP平台开发的利器——Android Studio for Platform

ASfP: 增强AOSP平台开发的利器——Android Studio for Platform Android Studio for Platform (ASfP) 是一个为使用 Soong 构建系统构建的 Android 开源项目&#xff08;AOSP&#xff09;平台开发者而设计的 Android Studio IDE 版本。与标准 Android Studio 不同&#xff0c;…

福建福州大型钢结构件3D扫描全尺寸三维测量平面度平行度检测-CASAIM中科广电

高精度三维扫描技术已经在大型工件制造领域发挥着重要作用&#xff0c;特别是在质量检测环节&#xff0c;高效、高精度&#xff0c;可以轻松实现全尺寸三维测量。本期&#xff0c;我们要分享的应用是在大型钢结构件的关键部位尺寸及形位公差检测。 钢结构件&#xff0c;是将多…

2023版 STM32实战1 LED灯驱动(电路与代码都讲解)

电路图 常规画法&#xff08;带限流电阻计算公式&#xff09; 设LED 电流为20mA(统一单位为 0.02A) 电压为3.3V 限流电阻(电源电压-负载正向工作电压)/工作电流 限流电阻(5V-3.3V)/0.02mA1.7/V0.02A85R 省事画法&#xff08;直接用IO输出&#xff09; 代码&#xff08;直…

学习pytorch11 神经网络-非线性激活

神经网络-非线性激活 官网文档常用1 ReLUinplace 常用2 Sigmoid 代码logs B站小土堆学习pytorch视频 非常棒的up主&#xff0c;讲的很详细明白 官网文档 https://pytorch.org/docs/stable/nn.html#non-linear-activations-weighted-sum-nonlinearity 常用1 ReLU 对输入做截断…

Scrapy+Selenium自动化获取个人CSDN文章质量分

前言 本文将介绍如何使用Scrapy和Selenium这两个强大的Python工具来自动获取个人CSDN文章的质量分数。我们将详细讨论Scrapy爬虫框架的使用&#xff0c;以及如何结合Selenium浏览器自动化工具来实现这一目标。无需手动浏览每篇文章&#xff0c;我们可以轻松地获取并记录文章的…

OpenCV实现的F矩阵+RANSAC原理与实践

1 RANSAC 筛选 1.1 大致原理 Random sample consensus (RANSAC)&#xff0c;即随机抽样一致性&#xff0c;其是一种用于估计模型参数的迭代方法&#xff0c;特别适用于处理包含离群点&#xff08;outliers&#xff09;的数据集 RANSAC 的主要思想是随机采样数据点&#xff0…

SpringBoot文件上传-阿里云OSS

1.打开阿里云 说明&#xff1a;登录阿里云账号 2.点击AccessKey管理 3.创建AccessKey 说明&#xff1a;记得复制accessKeyId&#xff0c;accessKeySecret并保存起来 4. 点击对象存储OSS 5.创建Bucket 说明&#xff1a;创建储存桶 6.查看SDK示例 7.Java简单上传 8.上传文件流…

已解决 AttributeError: ‘str‘ object has no attribute ‘decode‘

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页: &#x1f405;&#x1f43e;猫头虎的博客&#x1f390;《面试题大全专栏》 &#x1f995; 文章图文并茂&#x1f996…

相对论的应用:GPS导航

“但是数学享有盛誉还有另一个原因&#xff1a;正是数学为精确的自然科学提供了一定程度的安全保障&#xff0c;而没有数学&#xff0c;它们就无法实现这一点。” “就现实而言&#xff0c;数学定律是不确定的&#xff1b;就其确定而言&#xff0c;它们并不涉及现实。” —阿尔…

Mysql高级——索引优化和查询优化(1)

索引优化 1. 数据准备 学员表插50万条&#xff0c; 班级表插1万条。 建表 CREATE TABLE class (id INT ( 11 ) NOT NULL AUTO_INCREMENT,className VARCHAR ( 30 ) DEFAULT NULL,address VARCHAR ( 40 ) DEFAULT NULL,monitor INT NULL,PRIMARY KEY ( id ) ) ENGINE INNO…

解决Win11/10中Edge浏览器页面加载不出来、打不开问题|有网但是打不开,加载不了

问题症状 edge浏览器打不开&#xff0c;有网络能正常上网&#xff0c;但是edge浏览器无法浏览。网络质量很高&#xff0c;但是页面就是加载不出来&#xff0c;详情如下&#xff1a; &#xff08;我是在科学上网后造成这样子的原因&#xff0c;现在将我的方法分享一下&#xff…

Flask狼书笔记 | 09_图片社交网站 - 大型项目的架构与需求

文章目录 9 图片社交网站9.1 项目组织架构9.2 编写程序骨架9.3 高级用户认证9.4 基于用户角色的权限管理9.5 使用Flask-Dropzone优化文件上传9.6 使用Flask-Avatars处理用户头像9.7 图片展示与管理9.8 收藏图片9.9 用户关注9.10 消息提醒9.11用户资料与账户设置9.12 首页与探索…

近万采集各种典故网站文章大全ACCESS\EXCEL数据库

一个学语文的朋友问我有没有关于各种典故以及万物由来的数据&#xff0c;我看了看手头的资料发现还真没有&#xff0c;而且网上似乎也没有这一类的成品&#xff0c;因此就用程序采集了一个典故网的文章。 分类统计情况有&#xff1a;成语典故&#xff08;共4198条&#xff09;、…

第三、四、五场面试

第三场 共享屏幕做题&#xff08;三道简单题&#xff09; 替换空格成%20&#xff08;双指针&#xff09; 删除升序链表中的重复元素&#xff08;指针&#xff09;有效的括号&#xff08;栈&#xff09; 第四场、第五场 自我介绍 项目拷打 整个项目架构rpc模块的情况分析的数…

【UE 粒子练习】01——练习前的准备

步骤 1. 首先在虚幻商城中搜索如下资产然后创建工程 2. 打开新建的示例工程然后新建一个空白关卡 3. 将“BP_DemoRoom”拖入视口 这里设置“Base Room Size”为5 移入“BP_DemoDisplay” 这里“Description”设置为“Standard Sprite Emitter” 通过快捷键Alt来快速复制一份“…

FireFly PowerBASIC RAD编程,调用PowerBASIC COM对象

一、序言 初步看了看PowerBASIC编程&#xff0c;很类似用VC注册窗体后调用回调函数&#xff0c;先是一个Dialog new&#xff0c;然后添加组件 Control add ......&#xff0c; 然后在处理 Windows MSG和发给组件的消息&#xff0c;这种编程方式和早期DOS 25x80屏幕上编程一样&…

UWB学习——day5

旁瓣的控制 在UWB&#xff08;Ultra-Wideband&#xff0c;超宽带&#xff09;通信系统中&#xff0c;对主瓣和旁瓣进行控制和优化是重要的&#xff0c;因为这直接影响了信号的传输质量、抗干扰性和系统性能。 旁瓣出现的原因 频谱泄露&#xff0c;根据傅里叶变换原理&#x…