C语言实现堆

news/2024/5/20 7:22:42 标签: 数据结构, 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;
}


http://www.niftyadmin.cn/n/181516.html

相关文章

【LeetCode】二叉树的后序遍历(递归,迭代)

目录 题目要求&#xff1a;给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 方法一&#xff1a;递归 方法二&#xff1a;迭代 思路分析&#xff1a; 代码展示&#xff1a; 复杂度分析 方法三&#xff1a;迭代进阶 思路分析&#xff1a; 代码展示&a…

编程题 (把字符串转为整数) (不要二)Java实现

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

数据结构与算法笔记--数据结构与算法基本知识

目录 1--数据结构 2--算法 3--算法分析 4--实例1&#xff1a;普通算法与秦九韶算法的运算效率比较 5--实例2&#xff1a;最大子列和问题 5-1--暴力求解法 5-2--分而治之 5-3--动态规划 5-4--完整代码 1--数据结构 定义&#xff1a;所有数据元素以及数据元素之间的关系…

基于DDS的SOA测试方案实现

随着以太网技术在车载网络中的应用&#xff0c;各种基于以太网的中间件也相继被应用在车内&#xff0c;如果对车载网络有过相关了解的小伙伴&#xff0c;对于作为中间件之一的DDS&#xff08;数据分发服务Data Distribution Service&#xff09;可能并不陌生&#xff1b;若没有…

SpringCloud源码探析(四)-OpenFeign使用及其原理

1.概述 在SpringCloud中&#xff0c;服务之间的调用方式可以通过ResTemplate进行调用&#xff0c;也可以通过Feign调用。ResTemplate的缺陷在于需要指定请求url&#xff0c;存在硬编码问题&#xff0c;导致代码难以复用和修改。而Feign调用就相对比较优雅&#xff0c;只需要配…

企业安全风险管理—应对风险

0x00 前言 已经知道要面临的所有的风险时&#xff0c;我们就需要去应对风险 0x01 应对风险 处置风险时可以采用四种基本方式&#xff1a;转移风险&#xff0c;规避风险&#xff0c;缓解或降低风险&#xff0c;接受风险。 1.转移风险 就是将风险转移给别人&#xff0c;比如…

【CVPR 2023】FasterNet论文详解

论文名称&#xff1a;Run, Don’t Walk: Chasing Higher FLOPS for Faster Neural Networks 论文地址&#xff1a;https://arxiv.org/abs/2303.03667 作者发现由于效率低下的每秒浮点运算&#xff0c;每秒浮点运算的减少并不一定会导致类似水平的延迟减少。提出通过同时减少冗…

Windows环境下jenkins war包下载及部署在tomcat中踩坑记录

一&#xff1a;安装tomcat 步骤见我的博客 二&#xff1a;官网下载jenkins https://jenkins.io/zh/download/ 点击以前的发行版本&#xff0c;随便选一个版本。因为我的谷歌双击点击下载没反应&#xff0c;所以我就去以前的版本里面下载了&#xff0c;果然就可以了 二、直接将…