数据结构--二叉树和堆

news2024/11/24 16:50:10

目录

1.基本概念

2.树的遍历方法

3.满二叉树&&完全二叉树

4.逻辑结构&&物理结构

5.推理公式

6.二叉树应用--堆

7.简单实现堆


1.基本概念

(1)这个里面的概念还是比较多的,但是大部分我们只需要了解即可,因为这个我们在离散数学里面已经学习过一些理论知识,这个地方就不在进行这个详细的赘述了;

(2)重点就是知道这个叶子结点和终端节点,双亲节点,孩子节点,树的高度,树的高度是从1开始的,这个是和离散数学里面相互区别点一个点,重点记忆一下就行了;

(3)每一个树都是有很多的节点组成的,但是这个节点都有自己的分支,我们把一个节点的分支的个数叫做这个节点的度,其中所有节点里面的度数的最大值就是这个树的度;

2.树的遍历方法

(1)我们知道这个树肯定是有这个val表示这个节点的数值,但是这个具体要定义多少个指针,这个是不确定的,因为我们的这个树的节点的个数是不确定的;

(2)这个时候一个很厉害的定义方法就出来了,不是这个树里面的节点个数不确定吗,这个时候我们只需要定义两个节点,一个节点就是左边节点,一个节点就是右边节点;

(3)在实现这个数据结构的时候,我们只需要先定义一个指针指向这个左边的节点,让后通过一个循环,让这个节点指向他右边的兄弟节点,如果没有的话就会直接到下一个父节点,这个就可以实现这个树的遍历;

3.满二叉树&&完全二叉树

(1)满二叉树:每一个节点都有两个子节点,一个是左边的节点,一个是右边的节点;

(2)完全二叉树:上面的每一层都是满的,但是最后一层没有满,满二叉树就是特殊的完全二叉树,后面的大部分介绍对于这个满二叉树通常都是使用的完全二叉树;

4.逻辑结构&&物理结构

(1)我们之前学习这个链表就介绍过这个逻辑结构和物理结构,这个逻辑结构就是这个我们自己想的图,例如这个脸表里面不同的节点之间使用一个有方向的箭头相互连接,实际上真实存在的这个链表之间通过指针就会直接找到下一个节点了,这个箭头就是我们认为的构想出来的,实际上就是不存在的;

(2)在二叉树里面,我们的这个完全二叉树(实际上是满二叉树)也是我们认为臆想出来的,在真实存储的时候,这个是使用数组的方式进行存储的;

(3)对于一个数组的序列,我们也是可以快速地画出它的逻辑结构的,直接按照这个父子节点的顺序排列即可;

5.推理公式

(1)通过一个数组,我们可以画出对应的逻辑结构,我们接下俩就是想要得到通过这个父节点的下标,找到这个子节点的下标,通过子节点的下边,推理出来这个父节点的下标;

(2)已知这个父节点下标i,左子树就是i*2+1,右子树就是i*2+2,已知这个子树的下标j,这个时候他的父亲节点的下标就是(j-1)/2因为这个进行的除法运算,这个时候即使两个子节点对应同一个父亲节点,这个也是可以计算出来的;

(3)我们上面介绍的这个满二叉树的逻辑结构就是一个数组,但是对于一个完全二叉树(非满二叉树),如果还是使用数组进行表示,这个时候就会造成这个空间的浪费,因为这个,满二叉树和完全二叉树都是有顺序的,我们对于这个完全二叉树里面没有节点的位置,就相当于是浪费一个数组的空间,因为这个地方如果放数据,我们上面的这个父子节点下标的推理公式就不成立了;

6.二叉树应用--堆

(1)这里的堆是一种数据结构,和我们之前在C语言里面说的malloc在对堆上面开辟空间的“堆”虽然写法是一样的,但是真正的意义是不一样的,malloc是操作系统里阿米的一个区域,我们在这个区域上面开辟内存空间,和这里的数据结构对截然不同,我们在数据结构里面学习的堆是用来排序的,是一种算法;

(2)堆的分类:大堆和小堆,这个定义是根据这个子节点和父亲节点val值的大小确定的,当一个二叉树里面的任何一个父亲节点的数值都大于这个子节点的,我们就称之为一个大堆,反之就是一个小堆;

(3)通过观察我们不难发现,小堆根是最小的,大堆的根是最大的,这个就可以找到一组数据里面的极值,后续我们回去学习这个如何把一个不是堆序列的数据经过这个顺序的变换使之成为这个大堆或者小堆,或者说是这个本来开始就是一个堆序列,经过数据的添加删除之后,他依然还是一个堆序列;

(3)堆的实质就是一个完全二叉树,这个就是堆和二叉树的联系;

7.简单实现堆

(1)头文件

typedef int HPDataType;

typedef struct Heap
{
	HPDataType* a;
	int size;
	int capacity;
}HP;

void Swap(HPDataType* p1, HPDataType* p2);
void AdjustUp(HPDataType* a, int child);
void AdjustDown(HPDataType* a, int n, int parent);

void HPInit(HP* php);
void HPDestroy(HP* php);
void HPPush(HP* php, HPDataType x);

这个里面包括这个数组的初始化,销毁,数据的插入,向上调整,向下调整;

(2)对一个简单的对堆,实际上就是一个数组,只不过结构上面更加体系化,我们想要插入数据,如果这个数据插入之后,原来的小堆还是小堆,这个直接插入即可,但是如果不是,我们就需要调整,因为这个小堆的父节点的值小,说明我们这个时候插入的数据比这个父节点还小,我们就需要要向上调整,把这个插入的节点和祖先节点进行比较,直到满足这个小堆的定义才停止;

因为我们插入的数据更加小,这个函数实现的就是向上调整;

void AdjustUp(HPDataType* a, int child)
{
	// 初始条件
	// 中间过程
	// 结束条件
	int parent = (child - 1) / 2;
	//while (parent >= 0)
	while (child > 0)
	{
		if (a[child] < a[parent])
		{
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

(3)如果我们想要实现堆的删除,这个地方的删除不是删除最后一个节点,这样的话直接size--即可,完全没有其他必要了,我们要删除的是这个堆顶部元素节点;

删除的方法就是把这个堆的顶部节点和这个最后一个节点互换,我们再size--把这个节点删除,这个时候堆的顶部节点删除了,但是这个时候肯定是不满足堆的定义的,因为我们把这个堆顶元素换掉了啊,我们这个时候就需要把这个节点向下进行查找,直到符合这个堆的定义才停止;仔细观察我们会发现,这个实际上就是一个简单的排序了,但是这个还不是真正的堆排序,但是前期阶段我们可以这样进行理解;

下面是这个向下调整的实现代码:

void AdjustDown(HPDataType* a, int n, int parent)
{
	// 先假设左孩子小
	int child = parent * 2 + 1;

	while (child < n)  // child >= n说明孩子不存在,调整到叶子了
	{
		// 找出小的那个孩子
		if (child + 1 < n && a[child + 1] < a[child])
		{
			++child;
		}

		if (a[child] < a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

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

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

相关文章

如何实现一套键盘鼠标控制两台计算机(Mouse Without Borders快速上手教程)

需求背景 当我们需要同时使用一台主机和一台笔记本的时候&#xff0c;如果使用两套键盘和鼠标分别操作各自的系统&#xff0c;非常地不便捷且非常占据桌面空间。那么如何使用一套键盘鼠标控制两台电脑呢&#xff1f; 需求实现 软件说明 我们可以使用微软官方的一款软件Mous…

vscode使用Git的常用操作

主打一个实用 查看此篇之前请先保证电脑安装了Git&#xff0c;安装教程很多&#xff0c;可自行搜索 一.初始化本地仓库&#x1f534; 使用vscode打开项目文件夹如图所使初始化仓库&#xff0c;相当于命令行的git init 二.提交到暂存区&#x1f534; 二.提交到新版本&#x1f…

07浅谈大语言模型可调节参数tempreture

浅谈temperature 什么是temperature&#xff1f; temperature是大预言模型生成文本时常用的两个重要参数。它的作用体现在控制模型输出的确定性和多样性&#xff1a; 控制确定性&#xff1a; temperature参数可以控制模型生成文本的确定性&#xff0c;大部分模型中temperatur…

RabbitMq - Java客户端基础【简单案例 +Work模型】

目录 1、前置知识 1.1、AMQP怎么理解 1.2、Spring AMQP是什么 1.3、为什么要了解Spring-AMQP&#xff1f; 2、使用Spring-AMQP实现一个发消息案例 3、Work模型 问题&#xff1a; 优化&#xff1a; 小结&#xff1a;Work模型的使用&#xff1a; 1、前置知识 1.1、AMQP怎…

PLC电源模块

PM电源模块 为CPU信号模块及 其他的扩展设备、其他用电设备&#xff08;如传感器&#xff09;提供工作供电 接线和开关 状态显示 灯的闪烁示意看手册 PS电源模块 为CPU信号模块及其他的扩展设备提供工作供电。PS(System Power Supply) 外形与PM电源模块类似&#xff0c;状…

妈妈带女儿美在心里

在这个充满温情与惊喜的午后&#xff0c;阳光温柔地洒落在每一个角落&#xff0c;仿佛连空气弥漫着幸福的味道。就在这样一个平凡的时刻&#xff0c;一段关于爱与成长的温馨画面&#xff0c;悄然在网络上绽放&#xff0c;引爆了无数人的心弦——#奚梦瑶2岁女儿身高#&#xff0c…

【Java】详解String类中的各种方法

创建字符串 常见的创建字符串的三种方式&#xff1a; // 方式一 String str "hello world"; // 方式二 String str2 new String("hello world"); // 方式三 char[] array {a, b, c}; String str3 new String(array); "hello" 这样的字符串字…

Windows环境安装Redis和Redis Desktop Manager图文详解教程

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Redis概述 Redis是一个开源的高性能键值对数据库&#xff0c;以其卓越的读写速度而著称&#xff0c;广泛用于数据库、缓存和消息代理。它主要将数据存储在内存中&#xff0…

零基础STM32单片机编程入门(九)IIC总线详解及EEPROM实战含源码视频

文章目录 一.概要二.IIC总线基本概念1.总体特征2.通讯流程 三.EEPROM介绍1.M24C08基本介绍2.向M24C08写一个字节时序图3.从M24C08读一个字节时序图 四.GPIO模拟IIC驱动M24C08读写五.CubeMX工程源代码下载六.讲解视频链接地址七.小结 一.概要 IIC(Inter&#xff0d;Integrated …

认识异常详解

1. 异常的定义&#xff1a; 在Java中&#xff0c;异常&#xff08;Exception&#xff09;是在程序执行过程中可能出现的错误或意外情况。异常可以分为两种类型&#xff1a;受检异常&#xff08;Checked Exception&#xff09;和未受检异常&#xff08;Unchecked Exception&…

C9联盟是什么?

九校联盟&#xff08;C9 League&#xff09;&#xff0c;简称C9联盟&#xff0c;是中国首个顶尖大学间的高校联盟&#xff0c;于2009年10月正式启动。 其成员都是国家首批“985工程”重点建设的一流大学&#xff0c;包括北京大学、清华大学、哈尔滨工业大学、复旦大学、上海交通…

水仙花数算法

一、水仙花的传说 希腊神话故事 传说希腊神话里&#xff0c;美少年纳西索斯&#xff08;Narcissus&#xff09;是希腊最俊美的男子&#xff0c;无数的少女对他一见倾心&#xff0c;可他却自负地拒绝了所有的人。这当中包括美丽的山中仙女伊可&#xff08;Echo&#xff09;。伊可…

(南京观海微电子)——MOS管原理及应用区别

MOS管&#xff1a; 全称为金属氧化物半导体场效应管&#xff08;Metal Oxide Semiconductor Field Effect Transistor&#xff09;&#xff0c;也被称为MOSFET&#xff08;Metal-Oxide-Semiconductor Field-Effect Transistor&#xff09;。它是一种半导体器件&#xff0c;常用…

Vulkan 学习(1)---- Vulkan 基本概念和发展历史

目录 Vulkan及其演化史Vulkan 基本概念基本术语 Vulkan 的原理Vulkan应用程序Vulkan的编程模型硬件初始化窗口展示表面资源设置流水线设置描述符和描述符缓冲池基于SPIR-V的着色器流水线管理指令的记录队列的提交 Vulkan及其演化史 目前主流的图形渲染API有OpenGL、OpenGL ES、…

Sequelize 操作 MySQL 数据库

安装 npm install --save sequelize安装驱动程序&#xff1a; npm install --save mysql2连接到数据库 要连接到数据库,必须创建一个 Sequelize 实例. 这可以通过将连接参数分别传递到 Sequelize 构造函数或通过传递一个连接 URI 来完成&#xff1a; const {Sequelize} re…

【Linux系统编程】文件系统

介绍&#xff1a; 文件系统是操作系统中负责管理和存储文件信息的软件结构&#xff0c;它组织和管理磁盘上的文件和目录&#xff0c;并定义了文件的存储结构。 Linux文件系统采用树状结构&#xff0c;只有一个根目录&#xff08;用“/”表示&#xff09;&#xff0c;其中含有下…

C++ 函数高级——函数的默认参数

函数默认参数 在C中&#xff0c;函数的形参列表中的形参是可以有默认值的 语法&#xff1a;返回值类型 函数名 &#xff08;参数 默认值&#xff09;{ } 示例&#xff1a; 正确代码&#xff1a; 运行结果&#xff1a;

黑马|最新AI+若依 |初识项目

本章主要内容是&#xff1a; 1.快速搭建了若依前后端项目在本地 2.实现了单表的增删改查快速生成 文章目录 介绍1.若依介绍2.若依的不同版本3.项目运行环境 初始化前后端项目1.下载若依项目2.初始化后端a.把表导入到数据库中b.更改application.yml文件 3.初始化前端a.安装依赖…

java集合(2)

目录 一. Map接口下的实现类 1. HashMap 1.1 HashMap常用方法 2. TreeMap 2.1 TreeMap常用方法 3. Hashtable 3.1 Hashtable常用方法 4.Map集合的遍历 4.1 根据键找值 4.2 利用map中的entrySet()方法 二.Collections类 1.Collections类中的常用方法 三. 泛型 1. 为什…

大连外贸建站公司wordpress主题模板

Robonaut萝卜纳特WP外贸站模板 适合用于工业机器人公司出口做外贸搭建公司官方网站使用的WordPress模板。 https://www.jianzhanpress.com/?p7091 优衣裳WordPress外贸建站模板 简洁的wordpress外贸独立站模板&#xff0c;适合服装、衣服、制衣外贸公司搭建公司官方网站使用…