二叉树的讲解

💓博主个人主页:不是笨小孩👀
⏩专栏分类:数据结构与算法👀 刷题专栏👀 C语言👀
🚚代码仓库:笨小孩的代码库👀
⏩社区:不是笨小孩👀
🌹欢迎大家三连关注,一起学习,一起进步!!💓

在这里插入图片描述

二叉树

  • 二叉树的性质
  • 二叉树的链式结构
    • 二叉树的遍历
      • 前序遍历
      • 中序遍历
      • 后序遍历
      • 层序遍历
    • 二叉树的销毁
    • 二叉树的查找

二叉树的性质

1.若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1) 个结点.
2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是 2^h-1.
3. 对任何一棵二叉树, 如果度为0其叶结点个数为n0 , 度为2的分支结点个数为02 ,则有n0 =n2 +1
4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h= . (ps: 是log以2为底,n+1为对数)
5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:

  1. 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
  2. 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
  3. 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子

二叉树的链式结构

一般来说,二叉树分为二叉链和三叉链,二叉链就是结构里面一个左孩子节点,一个右孩子节点,三叉链多了一个父亲节点,我们比较经常见的都是二叉链的,所以我们主要讲的也是二叉链。

结构:

typedef int BTDataType;

typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

我们在看任意一颗二叉树时,都可以将它分为三部分,根,左子树,右子树,左子树也可看成根,左子树,右子树,右子树也可看成根,左子树,右子树,因此二叉树定义是递归式的,我们后面的代码也是主要靠递归来实现的。

二叉树的遍历

二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次。

二叉树的遍历分为,前序遍历、中序遍历、后序遍历、层序遍历,其中前中后序遍历是递归定义的,而层序遍历是非递归遍历的。

前序遍历

前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。前序先访问根节点,再访问左子树,再访问右子树。

在这里插入图片描述

代码如下:

// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	printf("%d ", root->data);
	BinaryTreePrevOrder(root->left);
	BinaryTreePrevOrder(root->right);
}

递归图:
在这里插入图片描述
大家可以根据这个递归展开图好好理解一下,后面的二叉树基本操作都是需要用递归来实现的。

中序遍历

中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。

代码如下:

// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	BinaryTreeInOrder(root->left);
	printf("%d ", root->data);
	BinaryTreeInOrder(root->right);

}

后序遍历

后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。

代码如下:

// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}

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

这三种遍历本质上都是一样的,理解清楚一个,另外两个就很简单了。

层序遍历

层序遍历和其他三种都不一样,设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

在这里插入图片描述

那这个要怎么实现呢?

我们需要借助我们的队列,我们可以先把根节点入到队列里,然后开始出队列,只不过每次出的时候如果它的左孩子不为空就将左孩子入队列,右孩子不为空就将右孩子入队列,以此类推。我们就是利用了队列的先进先出,我们就可以轻松地完成层序遍历。

代码如下:

// 层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
	{
		QueuePush(&q,root);
	}
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front->left)
		{
			QueuePush(&q, front->left);
		}

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

二叉树的销毁

二叉树的销毁很简单,我们需要遍历一遍二叉树,但是我们用那种遍历呢,如果用前序,那么就会销毁根节点,就找不到它的左孩子和右孩子,明显是不合适的,最好的情况就是我们先去销毁它的左孩子,再去销毁他的右孩子,然后再销毁根节点,所以这里我们使用后序遍历是比较合适的。

代码如下:

// 二叉树销毁
void BinaryTreeDestory(BTNode* root)
{
	if (root == NULL)
	{
		return;
	}
	BinaryTreeDestory(root->left);
	BinaryTreeDestory(root->right);
	free(root);
}

二叉树的查找

二叉树的查找的基本思路也是遍历一遍二叉树,但是我们需要返回这个节点,这就给我们的难度增加了很多,我们这里想的是先看根节点是不是,如果不是就去他的左子树找,如果找到了就返回,否则就去它的右子树找,找到就返回该节点,最后都找不到我们就返回NULL.

代码如下:

// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->data == x)
	{
		return root;
	}

	BTNode* left = BinaryTreeFind(root->left, x);
	if (left != NULL)
	{
		return left;
	}

	BTNode* right = BinaryTreeFind(root->right, x);
	if (right != NULL)
	{
		return right;
	}

	return NULL;
}

最后带大家看一下会给我们带来好运的树:
在这里插入图片描述

今天的分享就到这里,感谢大家的关注和支持!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设计模式行为型——状态模式

目录 状态模式的定义 状态模式的实现 状态模式角色 状态模式类图 状态模式举例 状态模式代码实现 状态模式的特点 优点 缺点 使用场景 注意事项 实际应用 在软件开发过程中&#xff0c;应用程序中的部分对象可能会根据不同的情况做出不同的行为&#xff0c;把这种对…

windows环境下打印机无法打印的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

勘探开发人工智能技术:机器学习(1)

0 提纲 2.1 什么是机器学习 2.2 不确定性 2.3 数据类型 2.4 分类、回归、聚类 2.5 分类问题的训练与测试 2.6 性能评价指标 1 什么是机器学习 对于西瓜这个抽象类来说&#xff0c;它具有“色泽”&#xff0c;“根蒂”&#xff0c;“敲声”三个属性&#xff1a; 通过观察这个…

[SpringBoot3]基础篇

二、SpringBoot基础篇 2.1什么是SpringBoot SpringBoot是目前流行的微服务框架&#xff0c;倡导“约定优于配置”&#xff0c;其目的是用来简化新Spring应用的初始化搭建以及开发过程。SpringBoot提供了很多核心的功能&#xff0c;比如自动化配置starter&#xff08;启动器&a…

微服务与Nacos概述-2

微服务间消息传递 微服务是一种软件开发架构&#xff0c;它将一个大型应用程序拆分为一系列小型、独立的服务。每个服务都可以独立开发、部署和扩展&#xff0c;并通过轻量级的通信机制进行交互。 应用开发 common模块中包含服务提供者和服务消费者共享的内容 provider模块是…

Ansible的安装和配置

安装和配置 Ansible 安装所需的软件包 创建名为 /home/greg/ansible/inventory 的静态清单文件&#xff0c;以满足以下要求&#xff1a; 172.25.250.9 是 dev 主机组的成员 172.25.250.10 是 test 主机组的成员 172.25.250.11 和 172.25.250.12 是 prod 主机组的成员 172.2…

闭环控制方法及其应用:优缺点、场景和未来发展

闭环控制是一种基本的控制方法&#xff0c;它通过对系统输出与期望值之间的误差进行反馈&#xff0c;从而调整系统输入&#xff0c;使系统输出更加接近期望值。闭环控制的主要目标是提高系统的稳定性、精确性和鲁棒性。在实际应用中&#xff0c;闭环控制有多种方法&#xff0c;…

深入浅出:MyBatis的使用方法及最佳实践

这里写目录标题 添加MyBatis框架⽀持配置连接字符串和MyBatis配置连接字符串配置 MyBatis 中的 XML 路径 添加业务代码创建数据库和表添加用户实体类添加 mapper 接⼝添加 UserMapper.xml添加 Service层添加 Controller层 增删改操作增加操作删除操作修改操作 添加MyBatis框架⽀…

无感部署 - 蓝绿部署、AB测试、灰度发布

蓝绿部署 蓝绿部署&#xff08;Blue-Green Deployment&#xff09;是一种软件发布和部署的策略&#xff0c;旨在实现无缝的应用程序升级和回滚。在蓝绿部署中&#xff0c;同时存在两个环境&#xff1a;一个是当前稳定的生产环境&#xff08;蓝色环境&#xff09;&#xff0c;另…

Spring Cloud 智慧工地源码(PC端+移动端)项目平台、监管平台、大数据平台

智慧工地源码 智慧工地云平台源码 智慧建筑源码 “智慧工地”是利用物联网、人工智能、云计算、大数据、移动互联网等新一代信息技术&#xff0c;彻底改变传统建筑施工现场参建各方现场管理的交互方式、工作方式和管理模式&#xff0c;实现对人、机、料、法、环的全方位实时监…

国产航顺HK32F030M: 基于NTC负温度系数的温度计

前言&#xff1a; 家里的一个儿童澡盆附带的温度计坏掉了&#xff0c;拆解后发现这东西做的真垃圾&#xff01;索性自己做一个。拆下了里面的NTC热敏电阻&#xff0c;但是不知道NTC的性能参数&#xff0c;经过测量与查资料后&#xff0c;采用用中位值滤波 、 Steinhart-Hart方…

swagger 3.0 学习笔记

引入pom <dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency>配置 import io.swagger.models.auth.In; import io.swagger.v3.oas.annotati…

三级城市展示省市区树

展示效果 数据库展示 业务代码 /*** 省市区树*/VLicenseApiOperation("查询经纬度")ApiImplicitParam(name "FnCity", value "省市区树", dataType "FnCity")GetMapping("/districtlist")public AjaxResult districtlist…

strlen和sizeof的区别

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解C语言中的sizeof和strlen&#xff08;仅此一篇让你明白它们两的差别&#xff09;&#xff0c;如果大家觉得我写的不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 文章目录 strlensizeof 在…

Simulink仿真模块 -Scope

Scope模块的作用是显示仿真过程中生成的信号。它包含在以下库中: 库: Simulink / Commonly Used BlocksSimulink / SinksHDL Coder / Commonly Used BlocksHDL Coder / Sinks 如图所示: Simulink Scope 模块和 DSP System Toolbox™ Time Scope 模块显示时域信号。…

【APITable】教程:创建并运行一个自建小程序

1.进入APITable&#xff0c;在想要创建小程序的看板页面点击右上角的【小程序】&#xff0c;进入小程序编辑页面。 2.创建一个新的小程序区。 点击【 添加小程序】 点击创建小程序&#xff0c;选择模板&#xff0c;输入名字。 3.确定后进入小程序部署引导页面。 4.打开Xshell 7…

春秋云镜 CVE-2022-0410

春秋云镜 CVE-2022-0410 WordPress plugin The WP Visitor Statistics SQLI 靶标介绍 WordPress plugin The WP Visitor Statistics (Real Time Traffic) 5.6 之前存在SQL注入漏洞&#xff0c;该漏洞源于 refUrlDetails AJAX 不会清理和转义 id 参数。 登陆账户&#xff1a;u…

LeetCode 热题 100 JavaScript -- 74. 搜索二维矩阵

给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非递减顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 …

D* 算法完全解析(应该是全网最详细的吧)

花了几天时间学习了下 D* 算法&#xff0c;只能说熟悉了一下流程&#xff0c;远不能说掌握&#xff0c;算法实在是非常巧妙 参考 《制造车间无人搬运系统调度方法研究》 《基于D*Lite算法的移动机器人路径规划研究》 人工智能: 自动寻路算法实现(四、D、D*算法) D* 算法 D*路径…

java 文件/文件夹复制,添加压缩zip

复制文件夹,并压缩成zip 需求&#xff1a;创建A文件夹&#xff0c;把B文件夹复制到A文件夹。然后把A文件夹压缩成zip包 public static void main(String[] args) throws Exception {try {String A "D:\\dev\\program";String B "D:\\program";// 创建临…