数据结构_第十二关:二叉树的基础OJ题练习

news2024/11/15 10:21:35

目录

1.单值二叉树

2.相同的树

3.另一棵树的子树

4.反转二叉树

5.对称二叉树

6.二叉树的结构及遍历

扩展:如何判断是不是完全二叉树、二叉树的销毁

1)判断是不是完全二叉树

2)二叉树的销毁


1.单值二叉树

OJ题链接https://leetcode.cn/problems/univalued-binary-tree/

 思路:

  • 先判断左子树,左子树不为空的情况下,左子树的值不等于根的值,返回false
  • 在判断右子树,左子树不为空的情况下,左子树的值不等于根的值,返回false
  • 最后如果以上两个条件都不满足,说明左右孩子的值和根的值相同,进行递归调用
    返回该函数的左子树与上右子树

代码:

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

2.相同的树

OJ题链接https://leetcode.cn/problems/same-tree/

思路:

  1. p和q都为空,返回true
  2. p和q有一个为空,返回flase
  3. p和q都不为空,则判断他们的节点值是否相同,不相同返回false
  4. 上面都不满足,进行递归左右节点

注意:

  • 第一步和第二步不能互换,
  • 不用去管左子树和右子树是否为空的问题,因为递归下去以后就会帮你去判断

代码:

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

3.另一棵树的子树

OJ题链接https://leetcode.cn/problems/subtree-of-another-tree/

 

 思路:

  • 这道题主要是用root的子树去和subRoot进行比较
  • 有了上面判断两个树是否相同的经验,我们只需要递归root来与subRoot比较即可
  • 注意递归时使用   ||   (或),在左子树或右子树有一个与subRoot相同的子树即为true

代码:

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

4.反转二叉树

OJ题链接icon-default.png?t=N2N8https://leetcode.cn/problems/binary-tree-preorder-traversal/description/

思路:

  • 可根据后序遍历的想法,
  • 先遍历每一个节点,如果有节点时NULL,直接返回root
  • 不为NULL,继续递归遍历左子树,
  • 然后再遍历右子树
  • 最后将左子树和右子树进行交换

代码:

struct TreeNode* invertTree(struct TreeNode* root)
{
    if(root==NULL)
        return root;
    else
    {
        invertTree(root->left);
        invertTree(root->right);
        struct TreeNode* mp;
        mp=root->left;
        root->left=root->right;
        root->right=mp;
    }
    return root;
}

5.对称二叉树

OJ题链接https://leetcode.cn/problems/symmetric-tree/

 思路:

  • 用左子树的左和右子树的右进行比较,
  • 先判断root是否为NULL,
  • 建立一个字函数,传左子树的指针和右子树的指针
  • 然后判断左子树和右子树是否为NULL,都为NULL返回true,有一个为NULL返回false
  • 都不为NULL,继续判断其值是否相同,不相同返回false,
  • 相同,继续递归,传递  左的左和右的右 && 左的右和右的左,进行递归

代码:

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

6.二叉树的结构及遍历

OJ题链接https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=60&&tqId=29483&rp=1&ru=/activity/oj&qru=/ta/tsing-kaoyan/question-ranking

 思路:

看注释理解即可

#include <stdio.h>
#include <stdlib.h>

struct TreeNode
{
    char val;
    struct TreeNode* left;
    struct TreeNode* right;
};

//创建二叉树
struct TreeNode* rebulidTree(char* str, int* i)
{
    //= ‘#’直接返回,并将i++
    if(str[*i]=='#')
    {
        (*i)++;
        return NULL;
    }
    //不为‘#’首先malloc一个新的节点,并让root->val指向数组中对应下标位置的值
    struct TreeNode* root=(struct TreeNode*)malloc(sizeof(struct TreeNode));
    root->val = str[(*i)++];
    
    //递归左子树和右子树
    root->left = rebulidTree(str, i);
    root->right = rebulidTree(str, i);

    return root;
}

//中序遍历
void InOrder(struct TreeNode* 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;
    //这里传参一定一定要传地址,因为在递归过程中虽然i++过了,
    //但只是在局部的栈帧中,返回之后栈帧销毁,i还是不会变的
    struct TreeNode* root = rebulidTree(str,&i);

    InOrder(root);

    return 0;
}

扩展:如何判断是不是完全二叉树、二叉树的销毁

1)判断是不是完全二叉树

思路:

  • 和层序遍历的思想一样,利用队列的先进先出进行
  • 如果是完全二叉树,在出队列,出到NULL时队列后面的元素应全为空
  • 如果不是完全二叉树,在出队列,出到NULL时,队列后面的元素会有不为空的情况

  • 我们可以加入一个flag做个判断标志,在第一次遇到NULL是,将flag变为false

  • 在只会再遇到不为空的元素时,如果flag为false,直接返回false

 代码如下:

//判断二叉树是否为完全二叉树:
bool isCompleteTree(BTNode* root)
{
	BTNode* queue[1000];  //直接用树的结构来生成一个队列(只用到data变量,不用到左右孩子)

	int head = 0, tail = 0;    //head即队列的头节点,用来出数据,tail即队列的尾结点,用来入数据

	bool flag = false;      // 存储是否出现过空节点的标记

	queue[tail++] = root;   //先让队列的头=树的根节点

	while (head < tail) 
	{
		BTNode* curNode = queue[head++];
		
		//在第一次遇到NULL的时候,用flag进行记录
		if (curNode == NULL)
			flag = true;
		else 
		{
			if (flag)        // 如果之前出现过空节点,说明当前节点不是完全二叉树的节点
				return false;
			queue[tail++] = curNode->left;
			queue[tail++] = curNode->right;
		}
	}
	return true;
}

2)二叉树的销毁

思路:递归进行销毁,和后序遍历类似

void destroyTree(BTNode* root)
{
	if (root == NULL)
		return;
	destroyTree(root->left);
	destroyTree(root->right);
	free(root);
}

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

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

相关文章

传输协议特点大比拼之UDP

文章目录 前言一.UDP协议端的格式源端口号和目的端口号报文长度校验和 二.UDP的特点无连接面向数据报不可靠缓冲区 前言 本文将比较两种主要的传输协议 ,UDP的特点&#xff0c;以帮助读者更好地理解它们的应用场景和优缺点。 一.UDP协议端的格式 大家先来看一些UDP的报文格式…

企业应用程序单点登录

企业每天都依赖于各种企业应用程序&#xff0c;包括云和本地应用程序。这意味着用户必须经常输入更多密码才能访问这些应用程序并完成他们的工作。为了提高用户的工作效率、减少密码疲劳并使身份管理更有效&#xff0c;您的组织需要部署高效的 SSO 解决方案。 AD360 提供企业 …

[STM32F103C8T6]ADC转换

什么是ADC转换&#xff1f; ADC转换的全称是&#xff1a;Analog-to-Digital Converter&#xff0c;指模拟/数字转换器 ADC的性能指标&#xff1a; ADC分辨率&#xff1a; SSA与VREF-一起接到地&#xff0c;DDA与VREF接到3.3v&#xff0c;所以ADC转换的范围是0---3.3v 所以最后的…

计算机网络复习——第4章 4.2.3 4.2.4 4.3

4.2.3 IP 地址与 MAC 地址 IP地址&#xff1a;虚拟地址、软件地址、逻辑地址。 网络层和以上各层使用。 放在 IP 数据报的首部。 MAC地址&#xff1a;固化在网卡上的 ROM 中。硬件地址、物理地址。数据链路层使用。放在 MAC 帧的首部。IP 地址放在 IP 数据报的首部&#xff…

Windows命令提示符之常见命令--动态更新

序言&#xff1a; 在大家接触Windows电脑的过程中&#xff0c;一般是直接通过鼠标来进行操作&#xff0c;很少甚至没有用到过命令来执行操作&#xff0c;而想必大家都看过电影里面的黑客大神都是通过密密麻麻的指令来操作的&#xff0c;并且执行的速度也会比我们用鼠标块&…

【严重】Artifex Software Ghostscript 任意命令执行漏洞(POC已公开)(CVE-2023-28879)

漏洞描述 Artifex Software Ghostscript是美国Artifex Software公司的一款开源的PostScript解析器。 Artifex Ghostscript 10.01.0及之前版本中&#xff0c;如果写入缓冲区的数据比总长度少一个字节&#xff0c;则尝试写入转义字符&#xff0c;导致两个字节被写入。攻击者可通…

WPF入门(三)--事件Event调用

1、WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时&#xff0c;应用程序才停止运行。 ShutDown 是隐式或显式发生&#xff0c;可以通过指定 ShutdownMode 的属性值来进行设置。 对ShutdownMode选项的更改&#xff0c;可以直接在App.xaml中更改&a…

酒店管理系统(Servlet+JSP)

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java案例分…

【网络小知识】TCP协议介绍/三次握手,四次挥手的作用

前端开发人员需要了解三次握手和四次挥手的原因是&#xff0c;这些概念是在客户端和服务器端之间进行网络通信时所涉及到的 TCP 协议的基本知识。而对于前端来讲&#xff0c;如果页面中请求服务端数据时出现连接失败、延迟等问题&#xff0c;就需要对TCP协议中三次握手、四次挥…

VS——Visual Studio 2022 社区版——安装

VS——Visual Studio 2022 社区版——安装 下载安装官网下载&#xff1a;点击【免费Visual Studio 】即可下载安装界面&#xff1a;选择社区版 Community 安装先修改【安装位置】&#xff0c;选择【全部下载后安装】【工作负荷】选择 【使用C桌面开发】【语言包】点击【安装】&…

排序算法(二)

三、桶排序 先看定义&#xff1a; 桶排序会进行两次排序&#xff0c;一次将所有元素分配到不同的桶中&#xff0c;一次针对每个桶排序或再次排序所有元素。 练习题&#xff1a; 1&#xff09; 力扣https://leetcode.cn/problems/top-k-frequent-elements/这道题就是非常典型…

NFS能使使用者访问网络上别处的文件就像在使用自己的计算机一样

先关闭selinux跟防火墙 安装NFS yum install nfs-utils -y 配置共享目录 mkdir /webdata 赋权 chmod 755 /webdata 修改配置文件 vim /etc/exports 换顺序启动 systemctl start rpc-bind systemct start nfs 测试 showmount -e 客户端挂载 创建共享目录 mkdir /we…

BUUCTF-rip

https://www.cnblogs.com/refrain-again/p/15001283.html 看了这个文章 我起码能理解我们栈溢出的目的 在做题之前 我们需要先理解 栈的存储方法 从上往下看 就能理解入栈 说回这道题目 为什么这道题目是栈溢出 1.查看基本信息 checksec file 是kali下的elf文件 相当于w…

ASEMI代理ADI亚德诺AD8061ARTZ-REEL7车规级芯片

编辑-Z AD8061ARTZ-REEL7芯片参数&#xff1a; 型号&#xff1a;AD8061ARTZ-REEL7 −3dB小信号带宽&#xff1a;320MHz −3dB大信号带宽&#xff1a;280MHz 0.1 dB平坦度的带宽&#xff1a;30MHz 斜率&#xff1a;650V/μs 总谐波失真&#xff1a;-77dBc 输入电压噪声&…

Kotlin | 这些隐藏的内存陷阱,你应该熟记于心

作者&#xff1a;Petterp 引言 Kotlin 是一个非常 yes 的语言&#xff0c;从 null安全 &#xff0c;支持 方法扩展 与 属性扩展&#xff0c;到 内联方法、内联类 等&#xff0c;使用Kotlin变得越来越简单舒服。但编程从来不是一件简单的工作&#xff0c;所有简洁都是建立在复杂…

电子招标采购系统:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展

营造全面规范安全的电子招投标环境&#xff0c;促进招投标市场健康可持续发展 传统采购模式面临的挑战 一、立项管理 1、招标立项申请 功能点&#xff1a;招标类项目立项申请入口&#xff0c;用户可以保存为草稿&#xff0c;提交。 2、非招标立项申请 功能点&#xff1a;非招标…

使用SpringAOP的方式修改controller接口返回的数据

1为什么需要修改返回接口的数据&#xff1f; 先看一个关于返回接口数据中包含时间的接口&#xff0c;如下接口中的birth属性&#xff0c;是日期&#xff0c;假设我们不做任何处理&#xff0c;那么在页面&#xff0c;我们看到的将是如下的时间显示效果&#xff0c;这明显不是我…

NVM-无缝切换Node版本

NVM-无缝切换Node版本 如果未使用nvm之前已经下载了node&#xff0c;并且配置了环境变量,那么此时删除这些配置(Node的环境以及Node软件),使用nvm是为了在某些项目中使用低版本的node NVM下载 进入github的nvm readme&#xff1a; https://github.com/coreybutler/nvm-windows…

企业如何利用数据打造新的人才战略?

由于利率上升、能源价格上涨、政治不确定性、全球供应限制以及寻找和资助昂贵人才的问题&#xff0c;企业的优先事项&#xff0c;也就是人们的优先事项&#xff0c;正在以前所未有的速度发生转变。在数据的基础之上迅速做出正确决策&#xff0c;并灵活精准地向他人传达意义。 …

必要的项目管理软件因素

什么样的项目管理软件好&#xff1f;对于一个项目团队来说&#xff0c;从项目开始到项目结束&#xff0c;需要多个部门的配合。每个成员可能会参与一个以上的项目&#xff0c;这通常需要并行的多个项目。据介绍&#xff0c;国外90%以上的项目是用软件管理的&#xff0c;而中国只…