数据结构 - 堆

这篇博客将介绍堆的概念以及堆的实现。

1. 堆的定义:
首先堆的元素按照是完全二叉树的顺序存储的。
且堆中的某个节点总是不大于不小于其父节点的值。
根节点最大的堆叫做大堆,根节点最小的堆叫小堆。逻辑结构如下图所示:

大堆和小堆的存储方式是利用一个一维数组进行存储的,其物理存储结构如下:

因此我们可以利用数组的下标,通过子节点找到父节点,或通过父节点找到子节点,其关系如下:
        parent = ( child - 1 ) / 2; child =  parent * 2 + 1;
2. 堆的创建
那么,现在我们有一个数组 a[] = {8, 1, 4, 5, 3, 2};  在逻辑上可以看成一个完全二叉树,但是它还不是一个堆,我们要如何将其构建成一个堆呢?这里我们以构建一个小堆为例,我们从倒数第一个非叶子节点的子树开始调整,一直调整到根节点的树,就可以调整成堆,示意图如下:
3. 堆的插入 
堆的插入一般插入到数组尾部,在进行向上调整算法,直到满足堆的定义 ,示意图如下:

4. 堆的删除
 堆的删除是删除堆顶的数据,将堆顶的根数据与最后一个数据交换,在删除数组的最后一个元素,在进行向下调整堆。示意图如下:

5. 代码实现
typedef int HPDataType;

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

void HeapInit(HP* php);//堆的初始化
void HeapDestroy(HP* php);//内存释放
void HeapPush(HP* php, HPDataType x);//堆的创建
void HeapPop(HP* php);//删除根节点
HPDataType HeapTop(HP* php);//返回根节点
bool HeapEmpty(HP* php);//判空
int HeapSize(HP* php);//堆大小
void HeapInit(HP* php)
{
	assert(php);
	php->a = NULL;
	php->capacity = 0;
	php->size = 0;
}

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

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

void Adjustup(HPDataType* a, int child)//小堆调整
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] < a[parent])
		{
			Swap(&a[child], &a[parent]);

			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

void HeapPush(HP* php, HPDataType x)
{
	if (php->size == php->capacity)
	{
		int newCapacity = php->capacity == 0 ? 4 : php->capacity * 2;
		HPDataType* tmp = (HPDataType*)realloc(php->a, newCapacity * sizeof(HPDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		php->a = tmp;
		php->capacity = newCapacity;
	}
	php->a[php->size] = x;
	php->size++;
	Adjustup(php->a, php->size-1);
}

void AdjustDown(int* a, int n, int parent)//前提:左子树和右子树是大/小堆 
{
	int child = parent * 2 + 1;
	while (child < n)
	{
		//选出左右孩子中 小/大 的那个
		if (child+1 < n && a[child + 1] < a[child])//右孩子可能不存在
		{
			child++;
		}
		if (a[parent] > a[child])
		{
			Swap(&a[parent],&a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

void HeapPop(HP* php)//删除堆顶的数据
//首尾数据交换,再删除,再调堆
{
	assert(php);
	assert(!HeapEmpty(php));
	Swap(&php->a[0], &php->a[php->size-1]);
	php->size--;
	AdjustDown(php->a,php->size,0);
}

HPDataType HeapTop(HP* php) 
{
	assert(php);
	assert(!HeapEmpty(php));
	return php->a[0];
}

bool HeapEmpty(HP* php)
{
	assert(php);
	return php->size == 0;
}

int HeapSize(HP* php) 
{
	assert(php);
	return php->size;
}
6. 结果
完全二叉树:
int a[] = { 8,1,4,5,3,2 };
建堆:

打印根节点,删除根节点,内存释放: 
while (!HeapEmpty(&hp))
{
	int top = HeapTop(&hp);
	printf("%d\n", top);
	HeapPop(&hp);
}

HeapDestroy(&hp);


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

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

相关文章

ZJUBCA研报分享 | 《BTC/USDT周内效应研究》

ZJUBCA研报分享 引言 2023 年 11 月 — 2024 年初&#xff0c;浙大链协顺利举办为期 6 周的浙大链协加密创投训练营 &#xff08;ZJUBCA Community Crypto VC Course&#xff09;。在本次训练营中&#xff0c;我们组织了投研比赛&#xff0c;鼓励学员分析感兴趣的 Web3 前沿话题…

opencv解析系列 - 基于DOM提取大面积植被(如森林)

Note&#xff1a;简单提取&#xff0c;不考虑后处理&#xff08;填充空洞、平滑边界等&#xff09; #include <iostream> #include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" #include <opencv2/opencv.hpp> using namespace cv…

Ajax (1)

什么是Ajax&#xff1a; 浏览器与服务器进行数据通讯的技术&#xff0c;动态数据交互 axios库地址&#xff1a; <script src"https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> 如何使用呢&#xff1f; 我们现有个感性的认识 <scr…

【Prometheus】k8s集群部署node-exporter

​ 目录 一、概述 1.1 prometheus简介 1.2 prometheus架构图 1.3 Exporter介绍 1.4 监控指标 1.5 参数定义 1.6 默认启用的参数 1.7 prometheus如何收集k8s/服务的–三种方式收集 二、安装node-exporter组件 【Prometheus】概念和工作原理介绍-CSDN博客 【云原生】ku…

微信小程序使用 iconfont

base64 形式引入 首先我们点击 iconfont 项目中的 项目设置 按钮&#xff0c;位置如下图所示&#xff1a; 我们勾选图中所示三种字体格式&#xff0c;选择 base64 是为了将另外两种字体转为 base64 形式&#xff0c;而选择 woff 与 ttf 字体原因如下&#xff1a; TTF 兼容性更…

【自然语言处理】NLP入门(五):1、正则表达式与Python中的实现(5):字符串常用方法:对齐方式、大小写转换详解

文章目录 一、前言二、正则表达式与Python中的实现1.字符串构造2. 字符串截取3. 字符串格式化输出4.字符转义符5. 字符串常用函数函数与方法之比较 6. 字符串常用方法1. 对齐方式center()ljust()rjust() 2. 大小写转换lower()upper()capitalize()title()swapcase() 一、前言 本…

基于.Net 的图形验证码模块

&#x1f3c6;作者&#xff1a;科技、互联网行业优质创作者 &#x1f3c6;专注领域&#xff1a;.Net技术、软件架构、人工智能、数字化转型、DeveloperSharp、微服务、工业互联网、智能制造 &#x1f3c6;欢迎关注我&#xff08;Net数字智慧化基地&#xff09;&#xff0c;里面…

【探索程序员职业赛道:挑战与机遇】

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

本地部署推理TextDiffuser-2:释放语言模型用于文本渲染的力量

系列文章目录 文章目录 系列文章目录一、模型下载和环境配置二、模型训练&#xff08;一&#xff09;训练布局规划器&#xff08;二&#xff09;训练扩散模型 三、模型推理&#xff08;一&#xff09;准备训练好的模型checkpoint&#xff08;二&#xff09;全参数推理&#xff…

PaddlePaddle框架安装

提示&#xff1a;可在python环境中进行安装&#xff0c;避免环境污染&#xff0c;创建命令conda create -n xxx_name python3.9,激活conda activate xxx_name 第一步&#xff1a;查看计算机平台版本 在窗口输入查看命令&#xff0c;查看CUDA的版本 nvidia-smi 二、根据以下条件…

pycharm连接远程服务器解决远程服务器文件不同步问题

一、pycharm连接远程服务器 1.前提条件 linux已经安装好虚拟环境&#xff0c;并且虚拟环境已经有python的相关环境 conda create -n name python3.10 2.连接服务器 1.进入pycharm的Settings 2.在Project里找Python Interpreter 3.点击⚙&#xff0c;再点击add 4.选择SSH…

【C++从练气到飞升】02---初识类与对象

&#x1f388;个人主页&#xff1a;库库的里昂 ✨收录专栏&#xff1a;C从练气到飞升 &#x1f389;鸟欲高飞先振翅&#xff0c;人求上进先读书。 目录 ⛳️推荐 一、面向过程和面向对象初步认识 二、类的引用 1. C语言版 2. C版 三、类的定义 类的两种定义方式&#xff…

机器学习-04-分类算法-01决策树

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中分类算法&#xff0c;本篇为分类算法开篇与决策树部分。 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程…

如何在Win系统本地部署Jupyter Notbook交互笔记并结合内网穿透实现公网远程使用

文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 在数据分析工作中&#xff0c;使用最多的无疑就是各种函数、图表、…

【前端系列】CSS 常见的选择器

CSS 常见的选择器 CSS&#xff08;层叠样式表&#xff09;是一种用于描述网页样式的标记语言&#xff0c;它定义了网页中各个元素的外观和布局。在 CSS 中&#xff0c;选择器是一种用于选择要应用样式的 HTML 元素的模式。选择器允许开发人员根据元素的类型、属性、关系等来选…

【计算机视觉】图像处理算法(其他篇)

来源&#xff1a;《OpenCV3编程入门》&#xff0c;怀念毛星云大佬&#x1f56f;️ 说明&#xff1a;本系列重点关注各种图像处理算法的原理、作用和对比 漫水填充 漫水填充法是一种用特定的颜色填充连通区域&#xff0c;通过设置可连通像素的上下限以及连通方式来达到不同的填…

【零基础学习02】嵌入式linux驱动中原子操作基本实现

大家好,为了进一步提升大家对实验的认识程度,每个控制实验将加入详细控制思路与流程,欢迎交流学习。 今天给大家分享一下,linux系统里面并发与竞争具体实现,操作硬件为I.MX6ULL开发板。 第一:Linux系统并发与竞争简介 linux是一个多任务操作系统,存在多个任务操作同一个…

【SpringBoot框架篇】36.整合Tess4J搭建提供图片文字识别的Web服务

文章目录 简介文件下载引入依赖main函数中使用基于Springboot搭建OCR Web服务配置traineddata路径枚举用到的语种类型定义接口响应的json数据格式封装OCR服务引擎编写web提供服务的接口启动服务并且测试html demo扩展 项目配套代码 简介 Tess4J是一个基于Tesseract OCR引擎的J…

mysql的索引、事务、分库分表问题

1.了解MySQL的索引吗&#xff1f;它为什么使用Btree作为底层&#xff0c;而不是其他呢&#xff1f; 这里我们要谈的是其他数据结构的缺点&#xff0c;然后说说Btree的优点&#xff0c;也就看你对MySQL的Btree与其他数据结构熟不熟悉。 Hash &#xff08;1&#xff09;Hash 索引…

第五十五回 吴用使时迁偷甲 汤隆赚徐宁上山-以102flowers数据集为例训练ResNet50模型

汤隆说我家世代打造兵器&#xff0c;破连环马需要用钩镰枪&#xff0c;我会打造。还需要我的姑表哥&#xff0c;金枪手徐宁&#xff0c;因为他会钩镰枪法。汤隆和吴用商议了请徐宁上山的法子&#xff0c;派石迁去偷徐宁的宝贝雁翎锁子甲。 石迁到了东京&#xff0c;打听到徐宁住…