C语言实现堆

注:这里我们所实现的是大根堆(即父节点不小于子节点的堆)

目录

一,堆的介绍

二,堆结构的创建

三,接口实现

1,初始化与销毁

2,数据的插入与删除

3,其他接口


一,堆的介绍

两种结构:

在物理结构上,堆就是一块连续的储存空间,对应数组

在逻辑结构上,堆是一棵完全二叉树

两种形式:

大根堆:父节点不小于子节点

小根堆:父节点不大于子节点

二,堆结构的创建

三个成员,指向数组的指针datas,表示数组中有效数据个数的size,表示数组容量的capacity

typedef int HeapDataType;

typedef struct Heap
{
	HeapDataType* datas;
	int size;
	int capacity;
}Heap;

这里如果我们对比堆和顺序表,可以发现结构体的创建可以说是一摸一样的,我想这就体现出了数据结构的精髓在于思想的这点,同一个结构体因为使用方式的不同,从而使它发挥出了不同作用,变成了新的模样。

三,接口实现

1,初始化与销毁

初始化,在使用堆之前,置空堆的成员;

销毁,在使用堆之后,释放空间,置空堆的成员;

void HeapInit(Heap* pHeap);

void HeapInit(Heap* pHeap)
{
	assert(pHeap != NULL);

	pHeap->datas = NULL;
	pHeap->size = pHeap->capacity = 0;
}


void HeapDestroy(Heap* pHeap);

void HeapDestroy(Heap* pHeap)
{
	assert(pHeap != NULL);

	free(pHeap->datas);
	pHeap->datas = NULL;
	pHeap->size = pHeap->capacity = 0;
}

2,数据的插入与删除

void HeapPush(Heap* pHeap, HeapDataType x);

数据插入前首先检查容量是否足够,不够则需要扩容,空间足够后插入数据,但这时数据的结构可能不满足堆的要求了(大根堆要求父节点不小于子节点,新节点可能不满足这种关系),此时需要调整(这里的调整称为向上调整)

void HeapPush(Heap* pHeap, HeapDataType x)
{
	assert(pHeap != NULL);

	HeapCheckCapacity(pHeap);
	pHeap->datas[pHeap->size] = x;
	AdjustUp(pHeap->datas, pHeap->size);

	pHeap->size++;
}

向上调整的做法是首先找到新节点的父节点,通过比较大小来判断是否进行数据的交换(子节点大于父节点则交换,反之不需调整),如果进行了交换还需要继续判断,直到新数据到了合适的位置(满足堆的要求)

void AdjustUp(HeapDataType* datas, int child)
{
	int parent = (child - 1) / 2;

	while (child > 0)
	{
		if (datas[child] > datas[parent])
		{
			Swap(&datas[child], &datas[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

void Swap(HeapDataType* x, HeapDataType* y)
{
	HeapDataType temp = *x;
	*x = *y;
	*y = temp;
}
void HeapCheckCapacity(Heap* pHeap)
{
	if (pHeap->size == pHeap->capacity)
	{
		int newcapacity = 2 * pHeap->capacity;
		pHeap->datas = (HeapDataType*)realloc(pHeap->datas, sizeof(HeapDataType) * newcapacity);
		assert(pHeap->datas != NULL);

		pHeap->capacity = newcapacity;
	}
}

void HeapPop(Heap* pHeap); 

注意这里的删除操作,删除的是根节点

堆根节点的删除,首先交换数组首元素和尾元素的数据,然后进行调整(首尾元素数据交换后数据的结构可能不满足堆的要求),这里的调整称为向下调整

void HeapPop(Heap* pHeap)
{
	assert(pHeap != NULL);
	assert(HeapEmpty(pHeap) != true);

	Swap(&(pHeap->datas[0]), &(pHeap->datas[pHeap->size - 1]));

	pHeap->size--;
	AdjustDown(pHeap->datas, pHeap->size, 0);
}

与向上调整相似,向下调整的做法是首先找到根节点的子节点(较大的子节点),通过比较大小来判断是否进行数据的交换(子节点大于父节点则交换,反之不需调整),如果进行了交换还需要继续判断,知道根数据到了合适的位置(满足堆的要求) 

void Swap(HeapDataType* x, HeapDataType* y)
{
	HeapDataType temp = *x;
	*x = *y;
	*y = temp;
}
void AdjustDown(HeapDataType* datas, int size, int parent)
{
	int child = parent * 2 + 1;

	while (child < size)
	{
		if (child + 1 < size && datas[child] < datas[child + 1])
		{
			child += 1;
		}

		if (datas[parent] < datas[child])
		{
			Swap(&datas[parent], &datas[child]);

			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

3,其他接口

HeapDataType HeapTop(Heap* pHeap);查看根节点数据

HeapDataType HeapTop(Heap* pHeap)
{
	return pHeap->datas[pHeap->size - 1];
}


bool HeapEmpty(Heap* pHeap);判断堆是否为空

bool HeapEmpty(Heap* pHeap)
{
	return pHeap->size == 0 ? true : false;
}


int HeapSize(Heap* pHeap);查看堆有效数据的多少

int HeapSize(Heap* pHeap)
{
	return pHeap->size;
}

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

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

相关文章

力扣:最后一个单词的长度(详解)

前言&#xff1a;内容包括&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读 题目&#xff1a; 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组…

基于springboot实现留守儿童爱心网站平台【源码+论文】

基于springboot实现留守儿童爱心网站演示开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&…

qt 关于QtXlsx的编译 使用

版本&#xff1a;qt 5.14.0 qt creator4.11.0 平时用mingw编译器 QtXlsx源码下载地址&#xff1a;QtXlsxWriter&#xff1a;https://github.com/dbzhang800/QtXlsxWriter 在Qt的XLSX模块提供了一组类来读写Excel文件。它不需要 Microsoft Excel&#xff0c;可以…

EM7电磁铁的技术参数

电磁铁可以通过更换电磁铁极头在一定范围内改善磁场的大小和磁场的均匀度 &#xff0c;并且可以通过调整极头间距改变磁场的大小。主要用于磁滞现象研究、磁化系数测量、霍尔效应研究、磁光实验、磁场退火、核磁共振、电子顺磁共振、生物学研究、磁性测量、磁性材料取向、磁性产…

期货黄金交易平台重要吗?有哪些显著的期货黄金交易平台优势?

黄金交易平台就是可以在其上面做黄金买卖交易的系统&#xff0c;是一种依靠行业应用软件而搭建的平台&#xff0c;里面会包含一些交易指标、趋势图表、K线。市场上的黄金交易平台很多&#xff0c;只有正规的期货黄金交易平台才值得信任。主要还是因为期货黄金交易平台优势所决定…

【五】线程安全VS线程不安全

1. Java内存模型的特征 Java内存模型是围绕着在并发过程中如何处理原子性、可见性和有序性这三个特征来建立。下面逐个看下哪些操作实现这三个特性&#xff1a; 1.1 原子性&#xff08;Atomicity&#xff09; 由Java内存模型来直接保证的原子性变量操作包括 read、load、assig…

【机器学习】线性回归

文章目录前言一、单变量线性回归1.导入必要的库2.读取数据3.绘制散点图4.划分数据5.定义模型函数6.定义损失函数7.求权重向量w7.1 梯度下降函数7.2 最小二乘法8.训练模型9.绘制预测曲线10.试试正则化11.绘制预测曲线12.试试sklearn库二、多变量线性回归1.导入库2.读取数据3.划分…

Linux--抓包-连接状态

目录 一、TCP&#xff1a; 1.抓包&#xff1a; 2.工具&#xff1a; 3.状态&#xff1a; 4.命令&#xff1a; 三次握手&#xff1a; 应答确认&#xff1a; 四次挥手 一、TCP&#xff1a; 面向连接、可靠的、流式服务 1.抓包&#xff1a; 三次握手、四次挥手 2.工具&…

数据库:Redis数据库

目录 一、数据库类型 1、关系型数据库 2、非关系型数据库 3、关系型非关系型区别 二、Redis数据库 1、什么是Redis 3、Redis特点 4、Redis为什么读写快 5、部署Redis数据库 6、redis管理 7、Redis数据库五大类型 8、Redis数据库基础使用 9、redis五大类型增删查 …

数据库管理-第六十三期 烦(20230327)

数据库管理 2023-03-27第六十三期 烦1 跨版本PDB迁移补遗2 BUGs3 就低不就高总结第六十三期 烦 上个周末呢&#xff0c;因为一些客户的事情整的一个周末都在干活&#xff0c;其中两天还搞到的晚上12点&#xff0c;几乎没咋休息&#xff0c;现在感觉贼累&#xff0c;继续写文章…

为什么我们认为GPT是一个技术爆炸

从23年初&#xff0c;ChatGPT火遍全球&#xff0c;通过其高拟人化的回答模式&#xff0c;大幅提升了人机对话的体验和效率&#xff0c;让用户拥有了一个拥有海量知识的虚拟助手&#xff0c;根据UBS发布的研究报告显示&#xff0c;ChatGPT在1月份的月活跃用户数已达1亿&#xff…

Java实习生------Redis哨兵机制详解⭐⭐⭐

“无数的我们被世界碾压成一缩黑团&#xff0c;无数的我们试图与世界抗争到底”&#x1f339; 参考资料&#xff1a;图解redis 目录 什么是哨兵机制&#xff1f; 哨兵机制主要干了哪三件事&#xff1f; 哨兵监控主节点的过程是怎样的&#xff1f; 判断主节点故障之后&…

Servlet---服务端小应用程序(服务器端的小组件)

零.前置知识 1.tomcat—服务器容器 tomcat就是一个服务器容器&#xff0c;通常说的将项目部署到服务器&#xff0c;就是将项目部署到tomcat中&#xff08;将项目放到tomcat容器中&#xff09;。 浏览器向服务器发送一个HTTP请求&#xff0c;请求访问demo09.html页面&#xf…

【Linux】进程相关笔记

文章目录查看进程方式批量化注释fork进程状态R状态S状态D状态T状态t状态退出码问题X&&Z状态僵尸进程的危害makefile 新知识孤儿进程查看进程方式 ls /proc ls /proc/13045 (可以查看到之情进程的属性) ps axj | head -1 && ps ajx | grep myprocess(文件名) |…

垃圾回收之CMS、G1、ZGC对比

ZGC&#xff08;The Z Garbage Collector&#xff09;是JDK 11中推出的一款低延迟垃圾回收器&#xff0c;它的设计目标包括&#xff1a; 停顿时间不超过10ms&#xff1b;停顿时间不会随着堆的大小&#xff0c;或者活跃对象的大小而增加&#xff1b;支持8MB~4TB级别的堆&#x…

【C++】string类的模拟实现

目录 一、前言 二、模拟实现 1、构造函数 2、拷贝构造函数 3、operator 4、operator[] 5、迭代器 6、string类的比较 7、string类的扩容 7.1、reserve 7.2、resize 8、string类的尾插 8.1、push_back 与 append 8.2、operator 9、string类的insert 9.1、插入字符…

deepin15.11无法正常输入汉字问题的解决

1,起因 本来是sougou输入法 但是由于自己突发奇想 在那瞎折腾 一不小心把配置给弄坏了 就再也回不到之前可以正常打印汉字的状态 历经两个小时的折腾 总算是又能输入汉字啦 耗费两个多小时 对当下的我来说时间成本着实有点高 但是把问题给解决了 总算还是有点收获 平时的学习过…

注意力机制 | CNN-BiLSTM-Attention基于卷积-双向长短期记忆网络结合注意力机制多输入单输出回归预测(Matlab程序)

注意力机制 | CNN-BiLSTM-Attention基于卷积-双向长短期记忆网络结合注意力机制多输入单输出回归预测(Matlab程序) 目录 注意力机制 | CNN-BiLSTM-Attention基于卷积-双向长短期记忆网络结合注意力机制多输入单输出回归预测(Matlab程序)预测结果评价指标基本介绍程序设计参…

qt 编译器 调试器

电脑版本&#xff1a;win10 64位 qt版本&#xff1a;based on Qt 5.14.0&#xff08;msvc 2017&#xff0c; 32位&#xff09; Qt Creator 4.11.0 qt安装包&#xff1a;qt-opensource-windows-x86-5.9.9.exe 安装过程一路next&#xff0c;安装完成后&#xff0c;默认使用的…

Spring IoC循环依赖问题

什么是循环依赖 循环依赖其实就是循环引⽤&#xff0c;也就是两个或者两个以上的 Bean 互相持有对⽅&#xff0c;最终形成闭环。⽐如A依赖于B&#xff0c;B依赖于C&#xff0c;C⼜依赖于A。 注意&#xff0c;这⾥不是函数的循环调⽤&#xff0c;是对象的相互依赖关系。循环调…