C语言实现最大堆max_heap(附完整源码)

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;
}

通过这段代码,我们可以实现最大堆数据结构,用于快速获取堆中的最大元素。

你可能感兴趣的:(c语言,算法,数据结构,C/C++)