堆的实现(堆的插入、堆的删除等)超级全

堆的实现(堆的插入、堆的删除等)超级全

在这里插入图片描述

文章目录

  • 堆的实现(堆的插入、堆的删除等)超级全
    • 一、前期基础知识
      • 1.树结构
        • ①树的定义
        • ②树的相关概念
        • ③二叉树
        • ④满二叉树和完全二叉树
          • a.满二叉树
          • b.完全二叉树
        • ⑤二叉树的性质
        • ⑥二叉树顺序结构的存储和链式结构的存储
          • a.顺序结构存储
          • b.链式结构存储
      • 2.堆结构
    • 二、堆结构/二叉树顺序结构存储的实现
      • 1.堆的初始化
      • 2.堆的销毁
      • 3.堆的插入
      • 4.堆的删除
      • 5.取堆顶数据
      • 6.堆的数据个数
      • 7.堆的判空

一、前期基础知识

1.树结构

①树的定义

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

②树的相关概念

在这里插入图片描述
节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:A的为6。
叶节点或终端节点:度为0的节点称为叶节点; 如上图:B、C、H、I…等节点为叶节点。
非终端节点或分支节点:度不为0的节点; 如上图:D、E、F、G…等节点为分支节点。
树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为6。
节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推。
树的高度或深度:树中节点的最大层次; 如上图:树的高度为4。
n个结点的树,有n-1条边。

一棵树有以下三部分组成
根节点,无前驱结点。
叶结点,度为0,又称终端结点
非终端节点,分支节点,度不为0

一棵树是由根节点和n颗子树构成的,子树一定不能相交,除了根节点外,每一个结点都有且仅有一个父节点。

如果不是树结构,那就是图结构。

③二叉树

每一个结点的度不一定都是2,整个二叉树里不存在度大于2的结点。

  1. 或者为空
  2. 由一个根节点加上两棵别称为左子树和右子树的二叉树组成

在这里插入图片描述
在这里插入图片描述

④满二叉树和完全二叉树
a.满二叉树

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

b.完全二叉树

完全二叉树
前(n - 1)层是满的
最后一层不满,但是从左到右必须连续排布,最少1个,最多2 ^ (n - 1)个。

⑤二叉树的性质
  1. 若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2 ^ (i - 1)个结点.
  2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2 ^ h - 1
  3. 对任何一棵二叉树, 如果度为0其叶结点个数为n0 , 度为2的分支结点个数为n2 ,则有n0 = n2 + 1
  4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h= log2底(n + 1)。(ps: 是log以2为底,n+1为对数)
  5. 将二叉树的每一个结点按层次从0到n编号:
    0
    1 2
    3 4 5 6
    7 8 (7,8为3的子节点)
    举个例子,这就是一个完全二叉树,0 = (1 - 1) / 2, 0 = (2 - 1) / 2,所以parent = (child - 1) / 2, leftchild = parent * 2 + 1, rightchild = leftchild + 1。
    但是注意,一定要在范围里。
⑥二叉树顺序结构的存储和链式结构的存储
a.顺序结构存储

顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。
在这里插入图片描述

b.链式结构存储

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。链式结构又分为二叉链和三叉链,二叉链就是两个指针+数据域,三叉链就是两个指针+指向父节点+数据域,我们暂时先不做重点讲解,后续笔者会进行讲解。

2.堆结构

1.一段连续的数组数据看作完全二叉树
2.必须是小堆或者大堆
小堆:任意一个父节点小于等于子节点
大堆:任意一个父节点大于等于子节点

typedef int HPDataType;

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

大家不妨再思考一下,数据结构的目的到底是什么,就是为了方便我们在内存中管理数据,再加上一些可以实现对这段数据进行操作的接口函数来实现我们的目的。

二、堆结构/二叉树顺序结构存储的实现

1.堆的初始化

void HPIni(HP* php)
{
	assert(php);
	php->a = NULL;
	php->size = 0;
	php->capacity = 0;
}

2.堆的销毁

void HPDestroy(HP* php)
{
	assert(php);
	free(php->a);
	php->a = NULL;
	php->size = 0;
	php->capacity = 0;
}

3.堆的插入

void Swap(HPDataType* p1, HPDataType* p2)
{
	assert(p1 && p2);
	HPDataType tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void HPAdjustUp(HPDataType* p, int child)
{
	assert(p);
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (p[child] < p[parent])
		{
			Swap(( & p[child]), ( & p[parent]));
			child = parent;
			parent = (parent - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

void HPPush(HP* php, HPDataType x)
{
	assert(php);
	if (php->size == php->capacity)
	{
		int newcapacity = php->capacity == 0 ? 4 : 2 * (php->capacity);
		HPDataType* tmp = (HPDataType*)realloc(php->a, newcapacity * sizeof(HPDataType));
		if (tmp == NULL)
		{
			perror("realloc");
			exit(-1);
		}
		php->a = tmp;
		php->capacity = newcapacity;
	}
	php->a[php->size] = x;
	php->size++;
	HPAdjustUp(php->a, (php->size - 1));
}

当你插入一个新的数据到堆里后,一定要记得你的结构实际是一个二叉树,而且以小堆为例,如果你插入的数据,比这个结点的父节点小,那就需要向上调整。

4.堆的删除

void HPAdjustDown(HP* p, int parent)
{
	assert(p);
	int child = parent * 2 + 1;//使用假设法
	while (child < (p->size))
	{
		if ((child + 1 < p->size) && (p->a[child + 1] < p->a[child]))
		//这个真的很重要,值得反复思考,进行交换
		{
			child = child + 1;
		}
		if (p->a[child] < p->a[parent])
		{
			Swap(&(p->a[child]), &(p->a[parent]));
			parent = child;
			child = child * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

void HPPop(HP* php)
{
	assert(php);
	assert(php->size > 0);
	Swap(&(php->a[0]), &(php->a[(php->size) - 1]));
	php->size--;
	HPAdjustDown(php, 0);
}

相信大家一定会有一些问题,因为堆的删除,是删除堆顶元素,大家可能会疑问,为什么不能直接头删。
原因有以下两点:
1.顺序表时间复杂度是O(N),过于复杂。
2.如果头删之后,整个数组是要向前挪一位的,整棵树的结构就全部改变了,父子关系,大小关系全部乱了,需要重新改。

所以我们重新选择一个方法,就是我们将堆顶元素和最后一个元素互换,再尾删,这样可以保证两颗子树从上到下的整个顺序都没有被改变,向下调整就只需要进入一颗子树继续调整就好啦。

5.取堆顶数据

HPDataType HPTop(HP* php)
{
	assert(php);
	assert(php->size > 0);//使用size
	return php->a[0];
}

6.堆的数据个数

int HPSize(HP* php)
{
	assert(php);
	return (php->size);
}

7.堆的判空

bool HPEmpty(HP* php)
{
	assert(php);
	/*if (php->size == 0)
	{
		return true;
	}
	else
	{
		return false;
	}*/
	return (php->size == 0);
}

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

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

相关文章

【JAVA】SpringBoot + mongodb 分页、排序、动态多条件查询及事务处理

【JAVA】SpringBoot mongodb 分页、排序、动态多条件查询及事务处理 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mongodb ↓ -->&…

多功能智能灯杆主要功能有哪些?

多功能智能灯杆这个词相信大家都不陌生&#xff0c;最近几年多功能智能灯杆行业发展迅速&#xff0c;迅速取代了传统路灯&#xff0c;那么多功能智能灯杆相比传统照明路灯好在哪里呢&#xff0c;为什么大家都选择使用叁仟智慧多功能智能灯杆呢&#xff1f;所谓多功能智能灯杆着…

如何开发有趣而富有创意的营销小游戏

在数字化时代&#xff0c;企业通过创意而独特的方式与目标受众互动&#xff0c;已成为提高品牌知名度和用户参与度的重要手段之一。其中&#xff0c;设计一款引人入胜的营销小游戏&#xff0c;不仅能吸引用户的眼球&#xff0c;还能有效传达品牌信息。以下是一些建议&#xff0…

人工智能-注意力机制之注意力汇聚:Nadaraya-Watson 核回归

查询&#xff08;自主提示&#xff09;和键&#xff08;非自主提示&#xff09;之间的交互形成了注意力汇聚&#xff1b; 注意力汇聚有选择地聚合了值&#xff08;感官输入&#xff09;以生成最终的输出。 本节将介绍注意力汇聚的更多细节&#xff0c; 以便从宏观上了解注意力机…

canvas高级动画001:文字瀑布流

canvas实例应用100 专栏提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。 canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重要的帮助。 文章目录 示例…

基于官方YOLOv4开发构建目标检测模型超详细实战教程【以自建缺陷检测数据集为例】

本文是关于基于YOLOv4开发构建目标检测模型的超详细实战教程&#xff0c;超详细实战教程相关的博文在前文有相应的系列&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a;《基于yolov7开发实践实例分割模型超详细教程》 《YOLOv7基于自己的数据集从零构建模型完整训练、…

electron windows robotjs 安装教程

Robotjs 安装 前言第一步 : 安装python第二步 : 安装Visual Studio 2022第三步 : 安装robotjs 前言 robotjs可以控制鼠标键盘&#xff0c;获取屏幕内容&#xff0c;配合electron可做很多自动化操作。windows下配置环境有很多坑&#xff0c;很多文章都太旧了。试了很多次发现了…

杰发科技AC7801——Flash模拟EEP内存分布情况

简介 本文记录了在使用AutoChips芯片Flash模拟EEP过程中的一些理解 核心代码如下 #include <stdlib.h> #include "ac780x_sweeprom.h" #include "ac780x_debugout.h"#define SWEEPROM_SIZE (2048UL) /* Ssoftware eeprom size(Byte) */ #define TE…

在新疆乌鲁木齐的汽车托运

在新疆乌鲁木齐要托运的宝! 看过来了 找汽车托运公司了 连夜吐血给你们整理了攻略!! ⬇️以下&#xff1a; 1 网上搜索 可以在搜索引擎或专业的货运平台上搜索相关的汽车托运公司信息。在网站上可以了解到公司的服务范围、托运价格、运输时效等信息&#xff0c;也可以参考其他车…

播放器开发(四):多线程解复用与解码模块实现

学习课题&#xff1a;逐步构建开发播放器【QT5 FFmpeg6 SDL2】 前言 根据第一章内容&#xff0c;我们首先可以先把解复用和解码模块完成&#xff0c;其中需要使用到多线程以及队列&#xff0c;还需要使用FFmpeg进行解复用和解码动作的实现。 创建BaseQueue基类 BaseQueue.h…

BUUCTF 谁赢了比赛? 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 小光非常喜欢下围棋。一天&#xff0c;他找到了一张棋谱&#xff0c;但是看不出到底是谁赢了。你能帮他看看到底是谁赢了么&#xff1f; 注意&#xff1a;得到的 flag 请包上 flag{} 提交 密文&#xff1a; 下载附…

代码随想录算法训练营第五十四天|392.判断子序列 115.不同的子序列

文档讲解&#xff1a;代码随想录 视频讲解&#xff1a;代码随想录B站账号 状态&#xff1a;看了视频题解和文章解析后做出来了 392.判断子序列 class Solution:def isSubsequence(self, s: str, t: str) -> bool:dp [[0] * (len(t)1) for _ in range(len(s)1)]for i in ra…

ky10 server x86 auditd安装(日志审计系统)

概述 Auditd工具可以帮助运维人员审计Linux&#xff0c;分析发生在系统中的发生的事情。Linux 内核有用日志记录事件的能力&#xff0c;包括记录系统调用和文件访问。管理员可以检查这些日志&#xff0c;确定是否存在安全漏洞&#xff08;如多次失败的登录尝试&#xff0c;或者…

2、分布式锁实现原理与最佳实践(二)

常见分布式锁的原理 4.1 Redisson Redis 2.6之后才可以执行lua脚本&#xff0c;比起管道而言&#xff0c;这是原子性的&#xff0c;模拟一个商品减库存的原子操作&#xff1a; //lua脚本命令执行方式&#xff1a;redis-cli --eval /tmp/test.lua , 10 jedis.set("produ…

【Redis】事务

文章目录 事务的概念事务操作MULTIEXECDISCARDWATCHUNWATCH 事务的概念 Redis 的事务和 MySQL 的事务概念上是类似的. 都是把⼀系列操作绑定成⼀组. 让这⼀组能够批量执 ⾏ Redis 的事务和 MySQL 事务的区别 弱化的原⼦性: redis 没有 “回滚机制”. 只能做到这些操作 “批量执…

基于 STM32F7 和神经网络的实时人脸特征提取与匹配算法实现

本文讨论了如何使用 STM32F7 和神经网络模型来实现实时人脸特征提取与匹配算法。首先介绍了 STM32F7 的硬件和软件特点&#xff0c;然后讨论了人脸特征提取和匹配算法的基本原理。接下来&#xff0c;我们将重点讨论如何在 STM32F7 上实现基于神经网络的人脸特征提取与匹配算法&…

2023年亚太杯数学建模A题解题思路(*基于OpenCV的复杂背景下苹果目标的识别定位方法研究)

摘要 由于要求较高的时效性和劳力投入&#xff0c;果实采摘环节成为苹果生产作业中十分重要的一部分。而对于自然环境下生长的苹果&#xff0c;光照影响、枝叶遮挡和果实重叠等情况普遍存在&#xff0c;这严重影响了果实的准确识别以及采摘点的精确定位。针对在复杂背景下苹果的…

Spring - Mybatis-设计模式总结

Mybatis-设计模式总结 1、Builder模式 2、工厂模式 3、单例模式 4、代理模式 5、组合模式 6、模板方法模式 7、适配器模式 8、装饰者模式 9、迭代器模式 虽然我们都知道有26个设计模式&#xff0c;但是大多停留在概念层面&#xff0c;真实开发中很少遇到&#xff0c;…

【迅搜03】全文检索、文档、倒排索引与分词

全文检索、文档、倒排索引与分词 今天还是概念性的内容&#xff0c;但是这些概念却是整个搜索引擎中最重要的概念。可以说&#xff0c;所有的搜索引擎就是实现了类似的概念才能称之为搜索引擎。而且今天的内容其实都是相关联的&#xff0c;所以不要以为标题上有四个名词就感觉好…

基于JavaWeb+SSM+Vue微信阅读小程序的设计和实现

基于JavaWebSSMVue微信阅读小程序的设计和实现 源码获取入口Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏[Java 源码获取 源码获取入口 Lun文目录 第1章 绪论 1 1.1 课题背景 1 1.2 课题意义 1 1.3 研究内容 1 第2章 开发环境与技术 3 2.1 MYSQL数据库 3 2.2 JSP技…