深入理解堆(Heap):一个强大的数据结构

.

个人主页:晓风飞

专栏:数据结构|Linux|C语言

路漫漫其修远兮,吾将上下而求索

文章目录

前言

堆的实现

基本操作

结构体定义

初始化堆(HeapInit)

销毁堆(HeapDestroy)

重要函数

交换函数(Swap)

上浮调整(UpAdd)

下沉调整(DnAdd)

重要操作

向堆中插入元素(HeapPush)

从堆中弹出元素(HeapPop)

堆的应用

完整代码

结语

前言

在计算机科学中,堆(Heap) 是一种非常重要的数据结构,广泛用于各种应用,从数据分析到算法优化,再到系统编程。堆的一个关键特性是其能够快速找到一组数中的最大或最小值。但是,什么是堆?如何在实际编程中实现和使用堆呢?

堆的实现

堆是一种特殊的完全二叉树。在一个最小堆中,每个父节点的值都小于或等于其子节点的值;相反,在一个最大堆中,每个父节点的值都大于或等于其子节点的值。这种属性使得堆能够快速访问、添加和删除其最大或最小元素。

基本操作

结构体定义

首先,堆是通过以下结构体定义的:

typedef struct Heap

{

HPDataType* a; // 指向堆数组的指针

size_t size; // 堆当前的大小

int capacity; // 堆的最大容量

} Hp;

这里,HPDataType* a 是一个指向动态分配数组的指针,该数组用于存储堆中的元素。size 表示堆中当前元素的数量,而 capacity是数组的最大容量。

初始化堆(HeapInit)

初始化函数 HeapInit 用于设置堆的初始状态:

// 初始化堆

void HeapInit(Hp* hp)

{

assert(hp); // 确保堆指针有效

hp->a = NULL; // 堆数组指针置空

hp->size = 0; // 初始化堆大小为0

hp->capacity = 0; // 初始化堆容量为0

}

此函数确保堆的开始状态为空,没有分配任何内存,且大小和容量都为零。

销毁堆(HeapDestroy)

为了避免内存泄漏,当堆不再需要时,应该使用 HeapDestroy 函数来释放其占用的内存:

// 销毁堆

void HeapDestroy(Hp* hp)

{

assert(hp); // 确保堆指针有效

free(hp->a); // 释放堆数组内存

hp->a = NULL; // 将堆数组指针置空

hp->size = hp->capacity = 0; // 重置堆大小和容量为0

}

这个函数释放了堆数组 a 的内存,并将指针置空,同时重置大小和容量。

重要函数

交换函数(Swap)

Swap 函数用于交换堆中两个元素的值。这在上浮和下沉调整中非常重要。

// 交换两个元素的值

void Swap(HPDataType* p1, HPDataType* p2)

{

HPDataType tmp = 0; // 临时变量用于交换

tmp = *p1;

*p1 = *p2