二叉树的构建,遍历等

news2025/1/11 14:15:52

1.叉树链式结构的实现

1.1前置说明

在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。

为了方便调试,我直接在主函数中来建立二叉树了,下面是一个简单的二叉树
在这里插入图片描述
二叉树节点结构体的定义,分别有数据,左孩子街边,右孩子节点

typedef int BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;
int main()
{
	BTNode* n1 = BuyBTNode(1);
	BTNode* n2 = BuyBTNode(2);
	BTNode* n3 = BuyBTNode(3);
	BTNode* n4 = BuyBTNode(4);
	BTNode* n5 = BuyBTNode(5);
	BTNode* n6 = BuyBTNode(6);
	n1->left = n2;
	n1->right = n4;
	n2->left = n3;
	n4->left = n5;
	n4->right = n6;
}

1.2二叉树的遍历

1.2.1 前序、中序以及后序遍历

学习二叉树结构,最简单的方式就是遍历。**所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉 树中的节点进行相应的操作,并且每个节点只操作一次。**访问结点所做的操作依赖于具体的应用问题。 遍历 是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。

在这里插入图片描述

按照规则,二叉树的遍历有:前序/中序/后序的递归结构遍历:

  1. 前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。
  2. 中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。
  3. 后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。

由于被访问的结点必是某子树的根,**所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为 根、根的左子树和根的右子树。**NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

二叉树的遍历操作用递归实现,下面是先跟根遍历的代码实现
在这里插入图片描述

//先序遍历
void PrevOrder(BTNode* root) {
	if (root == NULL) {
		printf("NULL ");
		return;
	}

	printf("%d ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);
}

至于中序遍历,后续遍历方法和先序遍历大同小异

//中序遍历
void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}

	InOrder(root->left);
	printf("%d ", root->data);
	InOrder(root->right);
}
//后序遍历
void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}

	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->data);
}
1.2.2层续遍历

顾名思义,就是一层一层的遍历
这里的层序遍历,要用到队列这个数据结构

void LevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
		QueuePush(&q, root);
	
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		printf("%d ", front->data);
		QueuePop(&q);

		if (front->left)
		{
			QueuePush(&q, front->left);
		}

		if (front->right)
		{
			QueuePush(&q, front->right);
		}
	}
	printf("\n");

	QueueDestroy(&q);
}

在这里插入图片描述
例如这里,1本来在队列中,出1后,分别判断左右子树节点是否为空,非空则将其入队,这时候队列中 为 2 4 队头为 2,出2,执行之前相同的操作, 3 入队,,然后再出4 , 5和6 入队,如此往复,就完成了层序遍历

1.2.3其他的一些功能实现
求二叉树的节点个数

思路,左子树节点+右子树节点再算上其根节点,也就是左+右+1
如果根节点为空,就直接返回0,

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

在这里插入图片描述这里顺着代码和图例理一遍,传入根节点,先是左节点,2,然后再由2调用,其左子树为3,3的左右子树为空 返回0+ 0 +1,也就是1,再回到2的的调用,返回1 +0 +1,也就是2,至此也就得出根节点的左子树的节点个数为2,同理,用该操作走完右子树,最后的节点个数就为2 + 3 +1 也就是6个

求二叉树的叶子节点个数

如何判断该节点是否为叶子节点呢?显而易见,谁的做左孩子,和右孩子节点都为空,则为叶子节点,这里依然将其分为左子树和右子树分开计算,遍历思想和上面计算所有节点差不多

// 叶子节点
int TreeLeafSize(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	if (root->left == NULL
		&& root->right == NULL)
	{
		return 1;
	}

	return TreeLeafSize(root->left)
		+ TreeLeafSize(root->right);

求树的高度

要树的高度由什么决定,左子树和右子树谁高,那么谁就决定树的高度
,算出子树高度后,再加上到根节点的高度1

在这里插入图片描述

//求树的高度
int TreeHeight(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}

	int leftHeight = TreeHeight(root->left);
	int rightHeight = TreeHeight(root->right);

	return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}
求第K层的节点个数

思路:用了一种相对的思想,比如第三层,对于第一层来说是第一层往下的第三层,对于第二层来说就是第二层的往下的第二层,对于第三层来说就他自己本身的第一层
用返回值一层带给上一层,如此往复直到最终带根节点的左右孩子,比较高度最终求出树的高度

// 求第k层的节点个数 k >= 1
int TreeKLevelSize(BTNode* root, int k)
{
	if (root == NULL)
		return 0;

	if (k == 1)
		return 1;

	// k > 1 子树的k-1
	return TreeKLevelSize(root->left, k - 1)
		+ TreeKLevelSize(root->right, k - 1);
}

在这里插入图片描述

查找二叉树的某个值

和遍历计算所有节点个数的思想差不多,只不过,在判断有点差异,如果节点的数据和要找的数据相符合就返回其这个节点的地址,这里最大的问题就是找到节点之后,该如何返回节点,在这里先判断根节点,如果根节点为空,直接返回空;再判断数据是否相等,相等就返回节点;然后再判断左子树,右子树,递归查找,哪个不为空,哪个就是返回的相应数据所在的节点

BTNode* TreeFind(BTNode* root, BTDataType x)
{

	if (root == NULL)
		return NULL;

	if (root->data == x)
		return root;

	struct BinaryTreeNode* ret1 = TreeFind(root->left, x);
	if (ret1)
		return ret1;

	struct BinaryTreeNode* ret2 = TreeFind(root->right, x);
	if (ret2)
		return ret2;

	return NULL;
}

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

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

相关文章

NC65中间件能启动,前端客户端启动失败,加载异常,卡住(org.owasp.esapi)

控制台输出错误 ESAPI.properties could not be loaded by any means. Fail.SecurityConfiguration class(org.owasp.esapi.reference.DefaultSecurityConfiguration) CTOR threw exception.效果图: 解决方案 添加如下参数: -Dorg.owasp.esapi.resou…

阿里云服务器ESC部署前后端分离项目完整流程

阿里云服务器ESC部署服务完整流程 准备安装软件1.安装jdk2.安装tomcat3.安装mysql 后端应用功能编写及部署编写一个简单的用户增删改查功能发布流程 前端功能应用及部署搭建前端框架准备:已安装npm 页面user.vueuserForm.vue 跨域问题安装nginx配置nginx 源码 准备 …

Maya的ai功能有哪些?Maya Assist是什么?

Autodesk Maya是一款流行的 3D 建模软件,艺术家和设计师使用它来创建现实的世界和表面。该软件以其与各种工具开发人员的合作而闻名,它允许多个工具的无缝集成以改进功能。Autodesk 的 Maya 刚刚发布了 Maya Assist,在 3D 建模和动画领域树立…

架构篇12:架构设计流程-评估和选择备选方案

文章目录 架构设计第 3 步:评估和选择备选方案评估和选择备选方案实战小结上一篇我们聊了设计备选方案,在完成备选方案设计后,如何挑选出最终的方案也是一个很大的挑战,主要原因有: 每个方案都是可行的,如果方案不可行就根本不应该作为备选方案。没有哪个方案是完美的。例…

MES系统计划排产功能,助你提升生产效率

MES系统的排产功能是基于企业的生产需求与资源情况进行制定的。首先,需要明确生产计划的目标和要求,包括计划产量、交货期限、生产能力等。然后,根据企业的生产资源情况,包括人员、设备、原材料等,制定生成计划。在MES…

Java链表(1)

🐵本篇文章将对单链表进行讲解,模拟实现单链表中常见的方法 一、什么是链表 链表是一种逻辑结构上连续而物理结构上不一定连续的线性表,链表由一个一个节点组成: 每一个节点中都由数据域(val)和指针域&…

食品加工厂可视化视频AI智能监管方案,助力工厂数字化运营

一、背景与需求分析 随着科技的不断进步和人们对食品安全和质量的日益关注,食品智慧工厂的建设成为了食品行业的一个重要趋势。智能化的食品工厂可以利用先进的技术和自动化系统,提高生产效率、降低监管成本,并确保产品的质量和安全。 行业…

使用GtkSharp下载zip包过慢问题解决方案

背景 安装GtkSharp这个包准备使用C#进行跨平台窗体应用程序开发,运行时发现其需要从github上下载【https://github.com/GtkSharp/Dependencies/raw/master/gtk-3.24.24.zip】这个依赖包,不知道是被墙了还是咋的,下载超时导致运行失败。 解决…

泛型..

1.泛型 所谓泛型 在类定义处是一种类型参数(我们平常所见到的参数指的就是方法中的参数 他接收有外界传递来的值 然后在方法中进行使用) 在类内部的话 则充当一种占位符 并且还提高了代码的复用率 何以见得提高了代码的复用率 其实就是通过对比使用了泛型技术和没有使用泛型技…

VS2019下各种报错合集(持续更新)

VS2019下的各种报错处理(长期更新),欢迎大家在评论区补充错误代码/描述 解决方案!!! 1、printf 代码运行到printf函数打印不出来内容,打断点之后,f10走过去,程序直接运行起来了,而…

Linux下串口編程遇到的接收数据错误及原因(

近日在调试串口的时候发现,另一设备向我ARM板的串口发送0x0d,我接收之后变成了0x0a,这是问题一;另外当对方向我发送一串数据,如果其中有0x11,那么我总是漏收此数,这是问题二。 由于问题莫名其妙…

深度视觉目标跟踪进展综述-论文笔记

中科大学报上的一篇综述,总结得很详细,整理了相关笔记。 1 引言 目标跟踪旨在基于初始帧中指定的感兴趣目标( 一般用矩形框表示) ,在后续帧中对该目标进行持续的定位。 基于深度学习的跟踪算法,采用的框架包括相关滤波器、分类…

【SVA断言_2023.01.24】

在RTL设计中,仿真时查看异常情况,异常出现时,断言会报警,断言占整个设计的比例应不少于30% assertion作用: 检查特定条件或事件序列的出现情况提供功能覆盖 断言失败的严重程度:$fatal(中止仿…

Oracle RAC 集群的安装(保姆级教程)

文章目录 一、安装前的规划1、系统规划2、网络规划3、存储规划 二、主机配置1、Linux主机安装(rac01&rac02)2、配置yum源并安装依赖包(rac01&rac02)3、网络配置(rac01&rac02)4、存储配置&#…

FitSM与ITIL及ITSM的对比

FitSM 是一种轻量级 IT 服务管理(ITSM)标准,其所有材料都是免费提供的,旨在促进 IT 服务提供中的服务管理,包括联合场景。但是,FitSM 适合您的组织吗?了解 FitSM 的适用性涉及两个方面。首先需要…

阿里云PAI-DSW部署ChatGLM3过程记录

1、申请免费的阿里云 PAI-DSW 资源,这个比较基础不做介绍了 2、从第二步开始,我们介绍部署ChatGLM3过程:PAI-DSW 资源界面如下图:点击开启新终端 3、默认目录下面建一个test目录,如下图: 4、执行命令cd te…

TPCC-MySQL

简介 TPC-C是专门针对联机交易处理系统(OLTP系统)的规范,一般情况下我们也把这类系统称为业务处理系统。 Tpcc-mysql是percona基于TPC-C(下面简写成TPCC)衍生出来的产品,专用于MySQL基准测试。其源码放在launchpad上&#xff0c…

2023年NOC大赛(学而思赛道)创意编程Python初中组决赛真题

2023年NOC大赛(学而思赛道)创意编程Python初中组决赛真题 题目总数:7 总分数:100 编程题 第 1 题 问答题 二进制回文 编程实现: 输入一个正整数,判断它的二进制形式是否是回文数,如果是输出True…

Web开发5:第三方扩展与部署

在Web开发中,第三方扩展和部署是提高开发效率和功能扩展的重要手段。第三方扩展可以帮助我们快速集成常用功能和工具,而部署则是将我们的应用程序发布到生产环境中。本文将介绍第三方扩展的重要性、如何选择和使用常见的第三方扩展,并讨论应用…

code server安装使用教程

1. 安装 1.1. 下载code-server安装包 类似这种文件:code-server-3.10.2-linux-amd64.tar.gz 解压:tar -xvf code-server-3.10.2-linux-amd64.tar.gz 1.2 (可选)建立软连接 ln -s path/to/code-server-3.10.2-linux-amd64/bin…