C语言实现最大堆max_heap(附完整源码)
堆(heap)是一种树形数据结构,用数组实现。堆分为最大堆和最小堆两种类型。最大堆的父节点的值总是不小于其子节点的值,而最小堆则相反。
下面我们来实现一个最大堆(max_heap)的代码。
先定义一个结构体,用于存储堆的一些信息:
typedef struct {
int *data; // 存储堆的数组
int size; // 当前堆的大小
int capacity; // 堆的容量
} MaxHeap;
然后定义一些堆的操作函数,包括创建堆、向堆中添加元素、移除堆中最大元素等等。
首先是创建堆函数,初始化并返回一个空的最大堆:
MaxHeap* create(int capacity) {
MaxHeap *heap = (MaxHeap*)malloc(sizeof(MaxHeap));
heap->capacity = capacity;
heap->size = 0;
heap->data = (int*)malloc(sizeof(int) * (capacity + 1)); // 根据容量分配数组空间
return heap;
}
接着是向堆中添加元素的函数,将新元素添加到堆的末尾后进行上浮操作:
void add(MaxHeap *heap, int value) {
if (heap->size >= heap->capacity) return; // 判断是否已满
heap->data[++heap->size] = value; // 先将元素添加到堆的最后一个位置上
int i = heap->size; // 记录它在堆中的位置
while (i > 1 && heap->data[i] > heap->data[i/2]) { // 如果元素比它的父节点大,则需要进行上浮操作
swap(&heap->data[i], &heap->data[i/2]);
i /= 2;
}
}
然后是移除堆中最大元素的函数,将最后一个元素替换到根节点后进行下沉操作:
void removeMax(MaxHeap *heap) {
if (heap->size <= 0) return; // 判断是否为空
heap->data[1] = heap->data[heap->size--]; // 将最后一个元素替换到根节点位置上
int i = 1; // 记录当前要下沉的元素的位置
while (i*2 <= heap->size) { // 如果它有子节点
int j = i*2; // 左子节点的位置
if (j+1 <= heap->size && heap->data[j+1] > heap->data[j]) { // 判断左右子节点大小
j++;
}
if (heap->data[i] >= heap->data[j]) break; // 如果当前节点比它的子节点都大,则不需要继续下沉了
swap(&heap->data[i], &heap->data[j]);
i = j;
}
}
最后给出一个交换两个元素的函数:
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
完整代码如下:
#include
#include
typedef struct {
int *data; // 存储堆的数组
int size; // 当前堆的大小
int capacity; // 堆的容量
} MaxHeap;
MaxHeap* create(int capacity) {
MaxHeap *heap = (MaxHeap*)malloc(sizeof(MaxHeap));
heap->capacity = capacity;
heap->size = 0;
heap->data = (int*)malloc(sizeof(int) * (capacity + 1)); // 根据容量分配数组空间
return heap;
}
void add(MaxHeap *heap, int value) {
if (heap->size >= heap->capacity) return; // 判断是否已满
heap->data[++heap->size] = value; // 先将元素添加到堆的最后一个位置上
int i = heap->size; // 记录它在堆中的位置
while (i > 1 && heap->data[i] > heap->data[i/2]) { // 如果元素比它的父节点大,则需要进行上浮操作
swap(&heap->data[i], &heap->data[i/2]);
i /= 2;
}
}
void removeMax(MaxHeap *heap) {
if (heap->size <= 0) return; // 判断是否为空
heap->data[1] = heap->data[heap->size--]; // 将最后一个元素替换到根节点位置上
int i = 1; // 记录当前要下沉的元素的位置
while (i*2 <= heap->size) { // 如果它有子节点
int j = i*2; // 左子节点的位置
if (j+1 <= heap->size && heap->data[j+1] > heap->data[j]) { // 判断左右子节点大小
j++;
}
if (heap->data[i] >= heap->data[j]) break; // 如果当前节点比它的子节点都大,则不需要继续下沉了
swap(&heap->data[i], &heap->data[j]);
i = j;
}
}
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
MaxHeap *heap = create(10);
add(heap, 3);
add(heap, 5);
add(heap, 1);
add(heap, 8);
add(heap, 10);
add(heap, 2);
add(heap, 6);
add(heap, 7);
add(heap, 4);
add(heap, 9);
for (int i = 1; i <= heap->size; i++) {
printf("%d ", heap->data[i]);
}
printf("\n");
removeMax(heap);
for (int i = 1; i <= heap->size; i++) {
printf("%d ", heap->data[i]);
}
printf("\n");
removeMax(heap);
for (int i = 1; i <= heap->size; i++) {
printf("%d ", heap->data[i]);
}
printf("\n");
removeMax(heap);
for (int i = 1; i <= heap->size; i++) {
printf("%d ", heap->data[i]);
}
printf("\n");
return 0;
}
通过这段代码,我们可以实现最大堆数据结构,用于快速获取堆中的最大元素。