二叉堆

title

二叉堆(Binary Heap)是一种特殊的堆,它是一棵完全二叉树,并满足堆的性质:对于每个节点x,其父节点的值小于等于x的值(最小堆),或者大于等于x的值(最大堆)。在二叉堆中,根节点存储的是堆中的最小(或最大)元素。

二叉堆通常使用数组来实现。假设根节点在数组中的下标为0,则第i个节点的左子节点在数组中的下标为2i+1,右子节点的下标为2i+2,父节点的下标为floor((i-1)/2)。这种实现方式使得二叉堆的任何操作的时间复杂度均为O(log n),其中n是堆中元素的数量。

二叉堆的基本操作包括:

  • 插入元素:将元素插入到堆中的正确位置,然后对堆进行调整,以满足堆的性质。
  • 删除元素:删除堆中的根节点,然后将堆的最后一个元素移动到根节点的位置,并对堆进行调整,以满足堆的性质。
  • 查找最小元素:返回堆的根节点。
  • 修改元素:将堆中的某个元素的值修改为新值,然后对堆进行调整,以满足堆的性质。

二叉堆的应用场景包括但不限于:

  • 堆排序:堆排序使用最大堆(或最小堆)来对数组进行排序。
  • 优先级队列:优先级队列使用最小堆(或最大堆)来实现,可以在O(log n)的时间内插入元素和返回队列中的最小(或最大)元素。
  • 图论算法:Dijkstra算法和Prim算法使用最小堆来实现。
  • 哈夫曼编码:哈夫曼编码使用最小堆来构建Huffman树。
  • 模拟系统:二叉堆可以用于模拟系统,其中每个事件都有一个优先级,优先级高的事件会先执行。

以下是二叉堆的C语言实现


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

#define MAX_HEAP_SIZE 100

// 二叉堆结构体
typedef struct binary_heap {
    int* heap;  // 堆的数组
    int size;   // 堆的大小
    int capacity;   // 堆的容量
} BinaryHeap;

// 创建二叉堆
BinaryHeap* createHeap(int capacity) {
    BinaryHeap* heap = (BinaryHeap*)malloc(sizeof(BinaryHeap));
    heap->heap = (int*)malloc(sizeof(int) * capacity);
    heap->size = 0;
    heap->capacity = capacity;
    return heap;
}

// 释放二叉堆
void destroyHeap(BinaryHeap* heap) {
    free(heap->heap);
    free(heap);
}

// 上滤
void siftUp(BinaryHeap* heap, int index) {
    int parent = (index - 1) / 2;
    int temp = heap->heap[index];
    while (index > 0 && heap->heap[parent] > temp) {
        heap->heap[index] = heap->heap[parent];
        index = parent;
        parent = (index - 1) / 2;
    }
    heap->heap[index] = temp;
}

// 下滤
void siftDown(BinaryHeap* heap, int index) {
    int temp = heap->heap[index];
    int child = 2 * index + 1;
    while (child < heap->size) {
        if (child + 1 < heap->size && heap->heap[child + 1] < heap->heap[child]) {
            child++;
        }
        if (heap->heap[child] < temp) {
            heap->heap[index] = heap->heap[child];
            index = child;
            child = 2 * index + 1;
        } else {
            break;
        }
    }
    heap->heap[index] = temp;
}

// 插入元素
void insert(BinaryHeap* heap, int value) {
    if (heap->size == heap->capacity) {
        printf("Heap is full.\n");
        return;
    }
    heap->heap[heap->size] = value;
    siftUp(heap, heap->size);
    heap->size++;
}

// 删除最小元素
void deleteMin(BinaryHeap* heap) {
    if (heap->size == 0) {
        printf("Heap is empty.\n");
        return;
    }
    heap->heap[0] = heap->heap[heap->size - 1];
    heap->size--;
    siftDown(heap, 0);
}

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

// 测试
int main() {
    BinaryHeap* heap = createHeap(MAX_HEAP_SIZE);
    insert(heap, 10);
    insert(heap, 5);
    insert(heap, 20);
    insert(heap, 3);
    printHeap(heap);
    deleteMin(heap);
    printHeap(heap);
    destroyHeap(heap);
    return 0;
}
powered by Gitbook© 2023 编外计划 | 最后修改: 2023-11-24 03:37:00

results matching ""

    No results matching ""