【数据结构】---详解二叉树--- ⌈知识点总结⌋ 和 ⌈常见力扣题目⌋ 确定不来看吗?

news2024/11/19 19:23:12

前言

❤️ 铁汁们大家好,欢迎大家来到出小月的博客里, 🤗🤗🤗之前呢,我分享了数据结构的栈和队列。。。。今天呢,给大家分享关于树的内容包括了树的结构、遍历和一些题目,希望大家看完我这篇文章都能够“涨芝士”,感觉小月写的还不错的话,记得👍🏻点赞加关注😘鼓励一下博主哦,不然下次可找不到我啦❗❗


作者简介

❤️ 作者的gitee:出小月;
❤️ 作者的主页:出小月的《程序员历险记》
❤️专栏:《C语言》,《数据结构初阶》
😊希望大家都能够:好好学习,天天编程❗❗❗


文章目录

    • 前言
    • 作者简介
    • 一、树概念及结构
    • 二、二叉树结构及遍历
    • 1、二叉树性质
    • 1、二叉树结构
    • 2、特殊的二叉树
      • 1️⃣ 满二叉树
      • 2️⃣完全二叉树
    • 3、二叉树的遍历
      • 1️⃣前序遍历
      • 2️⃣中序遍历
      • 3️⃣后序遍历
      • 4️⃣层序遍历
    • 三、二叉树常见OJ题练习
    • 1、树的结点的个数
    • 2、叶子节点的个数
    • 3、主函数
    • 总结


一、树概念及结构

🤗之前呢,我分享了顺序表、链表、栈和队列。这些都是线性结构,今天呢分享树的知识点,树呢是一种非线性的数据结构。把它叫做树呢?是因为它看起来像一颗倒挂的树,也就是说根朝上,而叶子朝下。

在这里插入图片描述
🤗这就是一棵树,那它怎么表示的呢?我们一般用左孩子、右兄弟。

typedef char tdatatype;
struct node
{
	struct node* firstchild;//第一个孩子节点
	struct node* nextbrother;//指向其下一个兄弟结点
	tdatatype data;
};

二、二叉树结构及遍历

1、二叉树性质

1、若根节点层数为i,则一颗非空二叉树的第i层上最多有2^(i-1);
2、若根节点层数为i,则深度为H的最大二叉树的最大节点数为(2^H)-1;
3、对于任何一颗二叉树,如果度为0其叶节点个数为n0,度为2的分支节点个数为n2,则有
n0=n2+1;

1、二叉树结构

🐹我们重点说的是二叉树。。。
任何一个二叉树都可以分成三个部分:
0️⃣ 根节点
1️⃣ 左子树
2️⃣ 右子树
我们这主要用的是分治算法:分而治之,大问题分成类似子问题,子问题再分成子问题……
那这是不是可以用递归啦?直到子问题不可再分割❗❗❗
在这里插入图片描述
🐷就像这个二叉树本来可以分为以A结点为根节点,还有左子树,右子树;
然后左子树又可以分成以B为根节点,还有左子树,右子树;
右子树也可以分成以C为根节点,还有左子树,右子树;

2、特殊的二叉树

1️⃣ 满二叉树

一个二叉树,如果每一层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是,如果一个二叉树N层,且总结点的个数是(2^N)-1,则它就是满二叉树。

2️⃣完全二叉树

完全二叉树由满二叉树而引出来,对于深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1-n的结点一一对应时称之为完全二叉树。

在这里插入图片描述

满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树

3、二叉树的遍历

在这里插入图片描述

1️⃣前序遍历

🐱就是先访问根节点,再访问左子树,最后访问右子树
就上面的树,我们先访问A结点
再访问左子树:左子树先访问B结点,再访问B结点的左子树D结点,然后再访问B结点的右子树,右子树先访问E结点,没有左子树,再访问H结点;
接下来访问右子树:先访问C结点,在访问左子树F结点,再访问右子树G结点

递归图就是这⬇️,大家一定要自己动手画一画,更加容易理解。。。
在这里插入图片描述
递归展开图比较复杂就展开一个简单的吧上面的⬆️
在这里插入图片描述
代码如下:

void prevorder(bitree* root)//递归前序 
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%c ", root->data);
	prevorder(root->left);
	prevorder(root->right);
}

2️⃣中序遍历

🐱就是先访问左子树,再访问根节点,最后访问右子树
代码如下:

void inorder(bitree* root)//递归中序
{
	if (root == NULL)
	{
	   printf("NULL ");
	   return;
	}
	inorder(root->left);
	printf("%c", root->data);
	inorder(root->right);
}

3️⃣后序遍历

🐱就是先访问根结点,再访问左子树,最后访问右子树

代码如下:


void lastorder(bitree* root)//递归后序
{
    if (root == NULL)
	{
	   printf("NULL ");
	   return;
	}
	lastorder(root->left);
	lastorder(root->right);
	printf("%c", root->data);
}

4️⃣层序遍历

🤗层序遍历的核心:首先将二叉树的根节点入队中,判断队列不为空,就输出队头的元素,
如果这个结点有孩子,就将孩子入队,将遍历过的节点出队列,循环以上操作,直到树为空

typedef struct queuenode
{
	struct queuenode* next;
	char data;
}qnode;
typedef struct queue
{
	qnode* head;
	qnode* tail;
}queue;
void levelorder(bitree* root)//非递归的层序遍历(用队列实现)核心:上一层带下一层
{
	queue q;
	queueinit(&q);
	if (root)
	{
		queuepush(&q, root);//头结点进栈
		while (!queueempty(&q))//如果这个队列不为空
		{
			bitree* front = queuefront(&q);//就出栈
			queuepop(&q);
			printf("%c", front->data);//并打印
			if (front->left)//如果这个结点的左子树存在就进队列
			{
				queuepush(&q, front->left);
			}
			if (front->right)//如果这个结点的右子树存在就进队列
			{
				queuepush(&q, front->right);
			}
		}
	}
}

三、二叉树常见OJ题练习

1、树的结点的个数

🐻这里用了一个三目运算符,如果这个结点是空就是0个结点,如果不为空就递归的遍历左子树的结点,和右子树的结点,还要加上根节点这个结点

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

2、叶子节点的个数

🐻叶子节点就是左子树和右子树都为0的结点,因此只一左子树和右子树都为0的这个结点返回1,然后递归遍历左子树,右子树。

int treeleafsize(bitree* root)
{
	if (root == NULL)
		return 0;
	if (root->left == NULL && root->right == NULL)
	{
		return 1;
	}
	return treeleafsize(root->left) + treeleafsize(root->right);
}

3、主函数

🐻这里我建了一棵树

int main()
{
	bitree* A = (bitree*)malloc(sizeof(bitree));
	A->data = 'A';
	A->left = NULL;
	A->right = NULL; 
	bitree* B = (bitree*)malloc(sizeof(bitree));
	B->data = 'B';
	B->left = NULL;
	B->right = NULL;
	bitree* C = (bitree*)malloc(sizeof(bitree));
	C->data = 'C';
	C->left = NULL;
	C->right = NULL;
	bitree* D = (bitree*)malloc(sizeof(bitree));
	D->data = 'D';
	D->left = NULL;
	D->right = NULL;
	bitree* E = (bitree*)malloc(sizeof(bitree));
	E->data = 'E';
	E->left = NULL;
	E->right = NULL;
	A->left = B;
	A->right = C;
	B->left = D;
	B->right = E;
	prevorder(A);//前序遍历
	return 0;
}

总结

🤗🤗今天关于树的知识点就分享到这里了,感觉小月写的还不错的话,记得点赞加关注哦👍👍,小月一直会分享记录自己的学习过程哦❗❗❗

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

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

相关文章

如何使用Github的Action实现博客的自动部署

如何使用Github的Action实现博客的自动部署 以下是详细的采坑记录,花费了不少时间。 现在的状态是,更新完博客时,需要执行以下的指令: hexo clean && hexo g && hexo d && git add . && git …

Git分布式版本控制工具

layout: post title: Git分布式版本控制工具 description: Git分布式版本控制工具 tag: 开发工具 文章目录git 基本配置与指令设置用户信息为常用指令设置别名解决gitbash乱码问题基础操作指令:初始化、添加到暂存区、提交到仓库、查看状态、日志版本回退git reset配…

智工教育:一级建造师《公路实务》考前必背知识点

一、路基工程 1.地基表层碾压处理压实度控制标准为:二级及二级以上公路一般土质应不小于90%;三、四级公路应不小于85%。 2.石质路堑施工技术 (1)应逐级开挖,逐级按设计要求进行防护。 (2)施工…

高效工具-局域网服务器访问公网

文章目录任务需求方法1:使用CCproxy代理简单介绍下载安装配置逻辑本机配置客户机配置成功测试方法2:修改MAC地址查询本机MAC地址修改内网服务器MAC地址打开rc-local.service服务添加Install段创建rc.local文件添加核心的修改MAC地址代码创建链接启动服务成功测试参考…

线上超市小程序开发有什么作用_超市小程序有什么功能呢

1。开发超市小程序有什么价值? 1、对于消费者来说:通过超市小程序能够更加直接的购买到想要的产品,消费者无需再到门店寻找商品可以直接通过超市小程序进行在线浏览;通过在线搜索的方式能够更加便捷的搜索到相应的商品&#xff0…

mysql连接池的实现

文章目录前言一、池化技术二、什么是数据库连接池三、为什么使用数据库连接池不使用连接池使用连接池长连接和连接池的区别四、数据库连接池运行机制五、连接池和线程池的关系六、连接池设计要点连接池设计逻辑构造函数初始化请求获取连接归还连接析构连接池前言 本文是mysql连…

模数转换电路

一、Exynos4412 A/D转换器概述 1. 概述 ADC(Analog-to-Digital Converter),就是模数转换器。从字面上看,A我们称为模拟信号(Analog signal),D我们称为数字信号(digital signal)。 模数转换器,在电子技术中即是将模拟信号转换成数字…

[附源码]java毕业设计家乡旅游文化推广系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

教你STM32做USB鼠标、键盘

使用CubeMX软件傻瓜式的配置,一键生成USB的HID驱动。 一、USB鼠标 1、CubeMX配置 ①、选择相对应的芯片 ②、配置时钟和Debug和debug ③、配置USB ④、生成代码 最好把这个也勾上,勾上以后每个外设配置不再都给你塞到main.c里,而是建一个.c…

简单的爬虫架构和网页下载器requests

目录 简单的爬虫架构: 网页下载器: URL管理器: 网页解析器: 网页下载器requests: 发送requests请求: 接收requests请求: requests操作实例: 简单的爬虫架构: 网页下载器: 负责通过URL将网页进行下载…

聊聊Vuex原理

背景 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。如果你已经灵活运用,但是依然好奇它底层实现逻辑,不妨一探究竟。 Vue 组件开发…

docker系统笔记-03镜像的创建管理和发布

镜像的获取 pull from registry (online) 从registry拉取 public(公有)private(私有) build from Dockerfile (online) 从Dockerfile构建load from file (offline) 文件导入 (离线) 镜像的基本操作 dock…

概率 | 【提神醒脑】自用笔记串联二 —— 数字特征、大数定律、统计量

本文总结参考于 kira 2023概率提神醒脑技巧班。 笔记均为自用整理。加油!ヾ(◍∇◍)ノ゙ 第一部分笔记详见 概率 | 【提神醒脑】自用笔记串联一 —— 事件、随机变量及其分布_西皮呦的博客-CSDN博客 一研为定! 四、随机变量的数字特…

cocos2dx 3D物理相关知识点汇总

(一)3D相关基础知识 网格(Mesh) 通常说的网格其实就是3D建模出来的形状。因为模型是由很多三角形组成,所以,就像网格一样。 纹理 纹理的作用就是给网格上色。 怎么上色的? 举个简单的例子。…

m基于GA遗传优化的生产工艺设备布置优化matlab仿真

目录 1.算法概述 2.仿真效果预览 3.核心MATLAB程序 4.完整MATLAB程序 1.算法概述 在设备布置的问题上,本文将作业车间设备布置这个多目标优化问题看成是包含布局面积,物流成本和生产工艺的连续优化的多行设备布置问题,使之更具有实际意义…

如何在 Rocky Linux 上安装 Apache Kafka?

Apache Kafka 是一种分布式数据存储,用于实时处理流数据,它由 Apache Software Foundation 开发,使用 Java 和 Scala 编写,Apache Kafka 用于构建实时流式数据管道和适应数据流的应用程序,特别适用于企业级应用程序和关…

robots.txt漏洞

robots.txt漏洞描述: 搜索引擎可以通过robots文件可以获知哪些页面可以爬取,哪些页面不可以爬取。Robots协议是网站国际互联网界通行的道德规范,其目的是保护网站数据和敏感信息、确保用户个人信息和隐私不被侵犯,如果robots.txt文件编辑的太过详细,反而会泄露网站的敏感…

[附源码]java毕业设计基于学生信息管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Delphi中关于PChar、Char数组、string[](ShortString)及结构体长度及占用空间的一些特性说明和测试

关于特性 1,string和Char数组都是一块内存, 其中存放连续的字符. string保存具体字符的内存对用户 是透明的, 由Delphi管理它的分配, 复制和释放, 用户不能干预2,关于ShortString,内存中用第一个字节来表示字符串的长度。FF255,所以这个特性…

【MySQL】MySQL复制与高可用水平扩展架构实战(MySQL专栏启动)

📫作者简介:小明java问道之路,专注于研究 Java/ Liunx内核/ C及汇编/计算机底层原理/源码,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。 &#x1…