返回

数据结构——堆(Heap)之大顶堆C语言实现

见解分享

堆是一种特殊性质的完全二叉树,每个结点的值大于等于其左右孩子的堆称为大顶堆;每个结点的值小于等于其左右孩子的堆称为小顶堆。大顶堆通常用于选择排序和优先级队列中。

1. 大顶堆的性质

  • 完全二叉树:除最后一层外,每一层都填满,最后一层从左到右依次填满。
  • 堆序性质:每个结点的值大于等于其左右孩子的值。

2. 大顶堆的实现

#include <stdio.h>
#include <stdlib.h>

#define MaxSize 100

typedef struct Heap {
    int data[MaxSize];
    int size;
} Heap;

// 初始化堆
Heap* initHeap() {
    Heap* heap = (Heap*)malloc(sizeof(Heap));
    heap->size = 0;
    return heap;
}

// 销毁堆
void destroyHeap(Heap* heap) {
    free(heap);
}

// 插入元素
void insert(Heap* heap, int data) {
    if (heap->size == MaxSize) {
        printf("堆已满\n");
        return;
    }
    heap->data[heap->size] = data;
    int i = heap->size;
    while (i > 0 && heap->data[i] > heap->data[(i - 1) / 2]) {
        int temp = heap->data[i];
        heap->data[i] = heap->data[(i - 1) / 2];
        heap->data[(i - 1) / 2] = temp;
        i = (i - 1) / 2;
    }
    heap->size++;
}

// 删除堆顶元素
int delete(Heap* heap) {
    if (heap->size == 0) {
        printf("堆为空\n");
        return -1;
    }
    int data = heap->data[0];
    heap->data[0] = heap->data[heap->size - 1];
    heap->size--;
    int i = 0;
    while (i < heap->size) {
        int max = i;
        if (2 * i + 1 < heap->size && heap->data[2 * i + 1] > heap->data[max]) {
            max = 2 * i + 1;
        }
        if (2 * i + 2 < heap->size && heap->data[2 * i + 2] > heap->data[max]) {
            max = 2 * i + 2;
        }
        if (max == i) {
            break;
        }
        int temp = heap->data[i];
        heap->data[i] = heap->data[max];
        heap->data[max] = temp;
        i = max;
    }
    return data;
}

// 打印堆
void printHeap(Heap* heap) {
    for (int i = 0; i < heap->size; i++) {
        printf("%d ", heap->data[i]);
    }
    printf("\n");
}

int main() {
    Heap* heap = initHeap();
    insert(heap, 10);
    insert(heap, 5);
    insert(heap, 12);
    insert(heap, 3);
    insert(heap, 7);
    insert(heap, 15);
    printHeap(heap);
    printf("堆顶元素:%d\n", delete(heap));
    printHeap(heap);
    destroyHeap(heap);
    return 0;
}

3. 大顶堆的应用

  • 选择排序:将大顶堆的根结点与末尾结点交换,然后重新调整堆,依次类推。
  • 优先级队列:堆顶元素是优先级最高的元素,可以快速找到优先级最高的元素。