16 C语言使用堆实现优先队列

#include "stdio.h"
#include "stdlib.h"

typedef int ElemType;
typedef struct MaxHeap {
    ElemType *arr;
    int size;
    int capacity;
} Heap;

Heap *initHeap() {
    Heap *heap = (Heap *) malloc(sizeof(Heap));
    if (heap == NULL) {
        exit(-1);
    }
    heap->size = 0;
    heap->capacity = 3;
    heap->arr = malloc(sizeof(ElemType) * heap->capacity);
    if (heap->arr == NULL) {
        exit(-1);
    }
    return heap;
}

//最大的会在最前面
int insert(Heap *heap, ElemType value) {
    if (heap->size == heap->capacity) {
        return 0;
    }

    // 先计算出插入位置 主要要先自增 因为是从1开始的
    int index = ++heap->size;
    // 开始向上堆化 直到符合规则为止
    /*
     * 在堆当中对于任意节点i 其父节点的索引是i/2并向下取整
     * 左子节点的索引是2*i 右子节点的索引是2*i+1
     * */
    while (index > 1 && value > heap->arr[index / 2]) {
        heap->arr[index] = heap->arr[index / 2];
        index = index / 2;
    }

    heap->arr[index] = value;
    return 1;
}

ElemType delete(Heap *heap) {
    if (heap->size <= 0) {
        return -1;
    }
    // 获取堆顶元素(最大值)
    ElemType max = heap->arr[1];

    // 用最后一个元素填补堆顶位置
    ElemType last = heap->arr[heap->size--];

    int index = 1;

    // 进行向下堆化调整(heapify),保持最大堆性质
    while (index * 2 <= heap->size) { // 因为是完全二叉树 所以只有在有左子树的情况下进行
        int child = index * 2; // 左孩子的索引

        // 如果右孩子存在,且右孩子比左孩子大,则选择右孩子
        if (child < heap->size && heap->arr[child] < heap->arr[child + 1]) {
            child += 1; // 选择右孩子
        }

        // 如果当前节点的元素大于等于子节点的元素,堆已经调整完毕,跳出循环
        if (last >= heap->arr[child]) {
            break;
        }

        // 否则将较大的子节点提升到当前节点的位置
        heap->arr[index] = heap->arr[child];

        // 更新索引,继续向下检查
        index = child;
    }

    // 将最后一个元素放到正确的位置
    heap->arr[index] = last;

    // 返回原堆顶元素(最大值)
    return max;
}


void printHeap(Heap *heap) {
    printf("打印堆的内容 ");
    for (int i = 1; i <= heap->size; ++i) {
        printf("%d ", heap->arr[i]);
    }
    printf("\n");
}

int main() {
    Heap *heap = initHeap();
    insert(heap, 5);
    insert(heap, 66);
    insert(heap, 3);
    insert(heap, 2);
    insert(heap, 1);
    insert(heap, 99);
    printHeap(heap);

    printf("取出堆的内容 ");
    for (int i = 0; i <= 3; ++i) {
        printf("%d ", delete(heap));
    }
}

运行效果

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