二叉树——经典练习题

news2024/10/5 17:17:09

目录

前言:

一、单值二叉树

        题目描述:

        思路分析:

        代码实现:

二、二叉树最大深度 

        题目描述:

        思路分析:

                代码实现: 

三、检查两颗树是否相同

        题目描述:

        思路分析: 

        代码实现:

四、另一颗树的子树

        题目描述:

        思路分析: 

        代码实现: 

五、二叉树的前序遍历

        题目描述:

        思路分析:

        代码实现:

六、二叉树的构建及遍历

        题目描述:

        思路分析: 

        代码实现:

最后:


前言:

        通过前面的学习,我们已经学习了二叉树的基础知识,以及二叉树功能的实现。我们学习讲究的是:知行合一。那我们一起来检验一下我们的学习成果吧!

一、单值二叉树

        题目描述:

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

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

        思路分析:

                单值二叉树就是二叉树每个节点的值都相同,这时,我们有两种思路去实现:

                方法一:再构造一个函数,把根节点的值传过去和左节点和右节点进行比较,如果相同,这个没啥意义,应用不同来判断,如果不同就返回假,为真就继续递归。

                方法二:用根节点和其左右节点进行比较,思路与上文类似。

                本题采用方法二。

        代码实现:

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

                以下是递归展开图,大致展示了函数调用过程,帮助大家理解:

                题目链接:. - 力扣(LeetCode) 

二、二叉树最大深度 

        题目描述:

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

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

        思路分析:

                此题一看不是和之前讲解的高度一样吗?对于我之前的说明不以为然的读者,可能会写出以下代码:

int maxDepth(struct TreeNode* root) {
    if(root == NULL)
    {
        return 0;
    }
    return maxDepth(root->left) > maxDepth(root->right) ? maxDepth(root->left)+1:maxDepth(root->right)+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;
}

                题目链接:. - 力扣(LeetCode)

三、检查两颗树是否相同

        题目描述:

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

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

        思路分析: 

                本题要求判断两颗树是否相同,那么,这么说明两颗树相同呢?无外乎就是一一比较,根与根比较,左子树与左子树比较,右子树与右子树比较,就这么简单。但,我们还要考虑的情况是:如果为空,这么判断,分两种情况:一、都为空:那就返回true。二、一个为空,另一个不为空。该放回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);
}

        题目链接:. - 力扣(LeetCode)

四、另一颗树的子树

        题目描述:

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

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

        思路分析: 

                本题一看没啥思路,这咋搞,很难办对吧。这时,突然想到,能不能放到数组里,然后看小数组是不是大数组的子集。但是,画图分析一下又好像不行。

                唯一的思路断了,这该怎么办?在思索之时,你突然想到:专业的事交给专业的人去干。这道题可不可以分解为这两步:第一步:先找到所有父节点。第二步:在经行判断两棵树是否相同。对于第二步和上题有异曲同工之妙,简单优化即可。

                第一步应该怎么办?很简单,直接把节点扔进去就行了,交给第二步去判断就行了,直到找到符合的节点。

                所以,这道题看起来很复杂,其实也不简单,对吧。

        代码实现: 

bool istree(struct TreeNode* root, struct TreeNode* subRoot)//判断操作
{
    if(root == NULL && subRoot == NULL)
    {
        return true;
    }
    if(root == NULL || subRoot == NULL)
    {
        return false;
    }
    if(root->val != subRoot->val)
    {
        return false;
    }
    return istree(root->left,subRoot->left) && istree(root->right , subRoot->right);
}

bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
    if(root == NULL)
    {
        return false;
    }
    if(root->val == subRoot->val && istree(root,subRoot))
    {
        return true;
    }
    return isSubtree(root->left,subRoot) || isSubtree(root->right , subRoot);//找父节点
}

        题目链接:. - 力扣(LeetCode)

五、二叉树的前序遍历

        题目描述:

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

        思路分析:

                二叉树的前序遍历,这不是说过吗?那好,给大家这个接口,看一看能否在leetcode官方上能不能运行通过。

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

                对于以上接口这里解释一下返回值这个问题。一个函数不是只有一个,那咱们应该返回啥,对于该问题,我们要先明白传过来的都代表什么意思。

                咱们首先明白,只要实现接口里的大逻辑即可,输入和打印咱们是不必实现的。打印是有leetcode官方写的代码实现的,你要实现打印肯定要知道这个树的的大小对吧。所以,那个returnsize是用来记录大小的。那为什么不用常量呢?因为:形参是实参的一份临时拷贝。要改变形参要传地址,地址需要用指针来接收。

                说了这么多,如果读者能够实现,就不用看博主的讲解,如果不行,就一件三连跟着博主继续走即可。

                对于我们现在来说,求一个树的节点个数是很简单的一件事,就不在赘述。知道了节点数,便可动态开辟一个数组用来存放数据。那么,我们接下来的难点为:如何把二叉树中的元素放到数组中。

                这件事也很简单,就是用前序遍历,把打印换成放元素仅此而已。

        代码实现:

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

        题目链接:. - 力扣(LeetCode)

六、二叉树的构建及遍历

        题目描述:

描述

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

输入描述:

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

输出描述:

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

         

        思路分析: 

                本题要求我们实现一个二叉树,并用中序遍历的方式将其打印出来。这道题很有难度,但有了前面的代码,在此时难度也不是很大了。本题的数据从外部输入,我们还要将其打印。所以,我们要自己实现接受外部的输入和用中序的方式对外打印,这部分代码难度不大,中序打印的类似实现已经讲过,不在赘述。

                本题讲解的难点为:构建二叉树。从以上的输入示例中,我们看到有‘#’这样的符号,但打印没它,那,我们可不可以写出以下代码:

if(a[(*pi)++] == '#')
    {
        return NULL;
    }

                乍一看没啥问题。但仔细想想问题就来了:这个的意思是我每次判断pi都加一,你觉得可行还是不可行。很显然,这不可行。所以,我们要把pi的++放入到{}内才能更好的符合我们的意图。我们放入字符采用的是先序遍历,这部分大家都能掌握,只不过,我们不清楚整颗二叉树的大小,所以,我们每次构建前都要用malloc开辟一下。

        代码实现:

#include <stdio.h>
#include<stdlib.h>
typedef char BTDataType;

typedef struct BinaryTreeNode {
    BTDataType data;
    struct BinaryTreeNode* left;
    struct BinaryTreeNode* right;
} BTNode;
BTNode* BTCreatTree(char* a,int* pi)
{
    if(a[*pi] == '#')
    {
        (*pi)++;
        return NULL;
    }
    BTNode* root = (BTNode*)malloc(sizeof(BTNode));
    root->data = a[(*pi)++];
    root->left = BTCreatTree(a,pi);
    root->right = BTCreatTree(a,pi);
    return root;
}
void BTNodePrint(BTNode* root)
{
    if(root == NULL)
    {
        return;
    }
    BTNodePrint(root->left);
    printf("%c ",root->data);
    BTNodePrint(root->right);
}
int main() {
   char a[101];
   scanf("%s",a);
   int i = 0;
   BTNode* ret = BTCreatTree(a,&i);
   BTNodePrint(ret);
    return 0;
}

        题目链接:二叉树遍历_牛客题霸_牛客网

最后:

        二叉树的学习,我们目前就告一段落了,后续的进阶内容会在c++部分讲解。今天讲解的题目中最后三道难度较大,还望各位读者在学习完后能够多多练习,这样才能够掌握。如在学习中,有啥问题可在评论区交流,也可私信。期待与读者再会。

完!

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

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

相关文章

EXCEL怎么计算一列数据里的最大连续重复次数?

有这样一列数据&#xff0c;怎么用EXCEL数据求出&#xff0c;重复出现的单/双的次数的最大值。 这里演示使用辅助列数据透视表。 一、单/双出现的次数的最大值 这个可不用辅助列&#xff0c;选中数据透视表将数据 单/双列放在行字段&#xff0c;和值字段&#xff0c;值字段会…

netplan

文章目录 前言官网配置文件默认配置NetworkManager 简介systemd-networkd 简介NetworkManager VS systemd-networkdNetplan 简介示例多个配置文件 前言 netplan 是 ubuntu 17.10 版本中引入的一种全新的命令行网络配置程序&#xff0c;用于在 ubuntu 系统中轻松管理和配置网络…

C语言 | Leetcode C语言题解之第114题二叉树展开为链表

题目&#xff1a; 题解&#xff1a; void flatten(struct TreeNode* root) {struct TreeNode* curr root;while (curr ! NULL) {if (curr->left ! NULL) {struct TreeNode* next curr->left;struct TreeNode* predecessor next;while (predecessor->right ! NULL)…

【DevOps】Jenkins + Dockerfile自动部署Maven(SpringBoot)项目

环境 docker_host192.168.0.1jenkins_host192.168.0.2 jenkins_host构建完成后把jar发布到docker_host&#xff0c;再通过dockerfile自动构建镜像&#xff0c;运行镜像 1 Jenkins安装 AWS EC2安装Jenkins&#xff1a;AWS EC2 JDK11 Jenkins-CSDN博客 AWS EC2上Docker安装…

此物一出天下反,Dora犹如优秀框架的粘合剂

引言&#xff1a;千里之行&#xff0c;始于足下。 如果你从事Android开发&#xff0c;请认真看完本篇文章&#xff0c;因为可能会颠覆你对Android开发的认识。 当夜空中繁星点点&#xff0c;一颗璀璨的流星划过&#xff0c;其辉光洒在古老的山谷之中&#xff0c;照亮了一个隐藏…

banner2.0自定义轮播布局

说明&#xff1a;最近碰到一个需求&#xff0c;让新闻列表实现轮播图的效果&#xff0c;也就是轮播新闻&#xff0c;然后样式必须按照ui设计的样式来弄&#xff0c;之前传统的banner&#xff0c;都是只轮播图片&#xff0c;没想到&#xff0c;这次居然要轮播新闻&#xff0c; 网…

夏老师小课堂(7) 免费撸Harmony0S应用开发者高级认证

点击上方 “机械电气电机杂谈 ” → 点击右上角“...” → 点选“设为星标 ★”&#xff0c;为加上机械电气电机杂谈星标&#xff0c;以后找夏老师就方便啦&#xff01;你的星标就是我更新动力&#xff0c;星标越多&#xff0c;更新越快&#xff0c;干货越多&#xff01; 关注…

C++ | Leetcode C++题解之第113题路径总和II

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<vector<int>> ret;unordered_map<TreeNode*, TreeNode*> parent;void getPath(TreeNode* node) {vector<int> tmp;while (node ! nullptr) {tmp.emplace_back(node->val);node …

高效的大型语言模型适应方法:提升基础性的解决方案

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

C++系列-static成员

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 概念 声明为static的类成员称为类的静态成员&#xff0c;用static修饰的成员变量&#xff0c;称之为静态成员变量&#xff0c;用static修饰的成员函数&#xff0c;称之为静态成…

Django框架css文件能正常加载,但是css样式不生效

最近运行一个Django项目&#xff0c;能正常启动运行&#xff0c;css文件也能够正常加载&#xff0c;但是css样式却没有正常渲染。 解决办法&#xff1a; 1、打开注册表&#xff1a;winR 2、找到&#xff1a;计算机\HKEY_CLASSES_ROOT\.css 修改&#xff1a;Content Type 值&…

【机器学习结合AI绘画工具】——开启艺术创作的新纪元

目录 一、AI绘画工具的发展历程 二、AI绘画工具的技术原理 实例说明 三、AI绘画工具在艺术创作中的应用 实例网站 四、AI绘画工具的影响与未来展望 结论 机器学习和人工智能&#xff08;AI&#xff09;在过去的十年里取得了显著的进展。特别是在艺术创作领域&#xff0c…

linux创建离线yum源给局域网机器使用

适用场景&#xff1a;在封闭的内网环境中&#xff0c;无法使用互联网进行安装各种rpm包的时候&#xff0c;离线yum源可以解决大部分问题&#xff0c;配置号后可直接使用yum进行安装包 1.准备好镜像源ISO&#xff1a; 例如以下示例&#xff0c;具体可参考自己的系统进行下载&a…

50-Qt控件详解:Input Display

#ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> //1.Combo Box控件 #include<QComboBox> //2.QFontComboBox控件 #include<QFontComboBox> #include<QLabel>//3.Line Edit控件 #include<QLineEdit> #include <QPushButton…

Installing Tinyproxy on CentOS 7 测试可用

Installing Tinyproxy on CentOS 7 For RHEL/CentOS 7 systems, Tinyproxy is part of EPEL (Extra Packages for Enterprise Linux). Install EPEL on CentOS 7 yum install epel-release -y yum update -y Install Tinyproxy on CentOS 7 yum install tinyproxy -y 编辑…

mysql中单表查询方法

大家好。我们知道&#xff0c;mysql有一个查询优化器的模块。当我们用sql语句查询表中记录时&#xff0c;会对这条查询语句进行语法解析&#xff0c;然后就会交给查询优化器来进行优化&#xff0c;优化后生成一个执行计划&#xff0c;这个执行计划表明了应该使用哪些索引进行查…

用这8种方法在海外媒体推广发稿平台上获得突破-华媒舍

在今天的数字时代&#xff0c;海外媒体推广发稿平台已经成为了许多机构和个人宣传和推广的有效途径。如何在这些平台上获得突破并吸引更多的关注是一个关键问题。本文将介绍8种方法&#xff0c;帮助您在海外媒体推广发稿平台上实现突破。 1. 确定目标受众 在开始使用海外媒体推…

[论文阅读笔记31]Mamba (Selective Structured State Space Model) 及其应用

最近想学一下Mamba模型&#xff0c;奈何看了很多视频还是感觉一知半解&#xff0c;因此做一篇笔记&#xff0c;顺便介绍一下Mamba结构作为CV backbone和时间序列预测领域的应用。 论文1. Mamba: Linear-Time Sequence Modeling with Selective State Spaces 0. Abstract 现有…

ModernC++(一)C++11

都在说Modern C和C不是一个东西&#xff0c;到底MordenC好在哪里&#xff0c;学了才有发言权。 why Morden C C 98的目标&#xff1a; 支持面向对象编程&#xff0c;支持泛型编程支持数据抽象 C 11的目标&#xff1a;使得C成为更好的适用于系统开发以及库开发的语言使得C语法…

宁夏银川、山东济南、中国最厉害的改名大师的老师颜廷利教授的前沿思想观点

在当代社会&#xff0c;一个响亮的声音穿越了传统的迷雾&#xff0c;它来自东方哲学的殿堂&#xff0c;由一位现代学者颜廷利教授所发出。他的话语&#xff0c;如同一股清泉&#xff0c;在混沌的世界里激荡着思考的波澜&#xff1a;"有‘智’不在年高&#xff0c;无‘智’…