20. 二叉堆
一、什么是二叉堆
二叉堆 也叫 优先队列(Priority Queue),它是一种特殊的队列,它取出元素的顺序是依照元素的 优先权(关键字)大小,而不是元素进入队列的先后顺序。二叉堆可以使用用数组表示的完全二叉树表示。任一结点的关键字是其子树所有结点的最大值或最小值。如果是最大值,则这个堆被称为 最大堆(MaxHeap)或者 大顶堆。如果是最大值,则这个堆被称为 最小堆(MinHeap)或者 小顶堆。
ADT MaxHeap
{
Data:
最大堆T∈MaxHeap, Item∈ElementType,
Operation:
MaxHeap CreateMaxHeap(int MaxSize); // 创建一个最大堆
int IsFull(MaxHeap H); // 判断最大堆是否已满
int IsEmpty(MaxHeap H); // 判断最大堆是否为空
void Insert(MaxHeap H, ElementType X); // 插入元素X
ElementType Delete(MaxHeap H, ElementType X); // 删除元素X
} ADT MaxHeap;
二、最大堆的表示
typedef int ElementType;
typedef struct HeapStruct
{
ElementType * Data;
int Size;
int Capacity;
} HeapStruct, * MaxHeap;
三、创建堆
#include <stdlib.h>
#include <limits.h>
/**
* @brief 最大堆的创建
*
* @param MaxSize 最大容量
* @return MaxHeap 指向最大堆的指针
*/
MaxHeap CreateMaxHeap(int MaxSize)
{
MaxHeap H = (MaxHeap)malloc(sizeof(HeapStruct));
H->Data = (ElementType *)malloc((MaxSize + 1) * sizeof(ElementType));
H->Size = 0;
H->Capacity = MaxSize;
// 定义哨兵为大于堆中所有可能元素的值,便于后序操作
H->Data[0] = INT_MAX;
return H;
}
四、插入元素
/**
* @brief 插入元素
*
* @param H 最大堆
* @param X 插入的元素
*/
void Insert(MaxHeap H, ElementType X)
{
int i = 0;
if (H->Size == H->Capacity)
{
printf("堆已满,无法插入元素\n");
return;
}
// i指向插入后堆中的最后一个元素的位置
i = ++H->Size;
// 从最后一个元素开始,依次向上比较,直到找到合适位置
for (; H->Data[i / 2] < X; i /= 2)
{
H->Data[i] = H->Data[i / 2];
}
// 插入元素
H->Data[i] = X;
}
H->Data[0] 是哨兵元素,它不小于堆中大的最大元素,用于控制循环的结束。
五、删除元素
/**
* @brief 删除元素
*
* @param H 最大堆
* @return ElementType 最大的元素
*/
ElementType Delete(MaxHeap H)
{
int Parent = 0, Child = 0;
ElementType MaxItem = 0, temp = 0;
if (H->Capacity == 0)
{
printf("堆为空,无法删除元素\n");
return 0;
}
MaxItem = H->Data[1]; // 获取最大元素
// 用最大堆中最后一个元素从根结点开始向下过滤下层结点
temp = H->Data[H->Size--];
// Parent指向当前结点,Parent * 2 指向左子结点
for (Parent = 1; Parent * 2 <= H->Size ; Parent = Child)
{
Child = Parent * 2;
// Child != H->Size,意味着有右子结点,Child指向左右子结点的较大者
if (Child != H->Size && (H->Data[Child] < H->Data[Child + 1]))
{
Child++;
}
if (temp >= H->Data[Child])
{
break; // 找到合适位置,退出循环
}
else
{
H->Data[Parent] = H->Data[Child]; // 移动temp元素到下一层
}
}
H->Data[Parent] = temp;
return MaxItem;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报