基于堆的优先队列

文摘   2024-10-11 07:30   内蒙古  

堆是一种特殊的树形数据结构,具有以下性质:

  • 堆是一个完全二叉树(Complete Binary Tree)。

  • 堆中的每个节点的值都必须满足堆的性质,即父节点的值必须大于或等于(最大堆)或小于或等于(最小堆)其子节点的值。

优先队列是一种特殊的队列,其中每个元素都有一个与之关联的优先级。元素的出队顺序是根据优先级确定的,具有较高优先级的元素先出队。

下面是一个基于堆的优先队列的 C 语言实现,包括创建、判空、判满、插入、查找最值、删除和摧毁等操作。

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

#define MAX_SIZE 100

typedef struct {
    int data[MAX_SIZE];
    int size;
} PriorityQueue;

// 初始化优先队列
void initialize(PriorityQueue *queue) {
    queue->size = 0;
}

// 判断优先队列是否为空
int isEmpty(PriorityQueue *queue) {
    return queue->size == 0;
}

// 判断优先队列是否已满
int isFull(PriorityQueue *queue) {
    return queue->size == MAX_SIZE;
}

// 插入元素到优先队列
void insert(PriorityQueue *queueint item) {
    if (isFull(queue)) {
        printf("Priority Queue is full. Cannot insert element.\n");
        return;
    }

    // 将元素插入到队尾
    queue->data[queue->size] = item;
    queue->size++;

    // 对插入的元素进行上浮操作,以维护堆的性质
    int i = queue->size - 1;
    while (i > 0 && queue->data[i] > queue->data[(i - 1) / 2]) {
        int parent = (i - 1) / 2;
        int temp = queue->data[i];
        queue->data[i] = queue->data[parent];
        queue->data[parent] = temp;
        i = parent;
    }
}

// 查找优先队列中的最大值(最大堆)或最小值(最小堆)
int findMax(PriorityQueue *queue) {
    if (isEmpty(queue)) {
        printf("Priority Queue is empty.\n");
        return -1;
    }

    return queue->data[0];
}

// 删除优先队列中的最大值(最大堆)或最小值(最小堆)
void deleteMax(PriorityQueue *queue) {
    if (isEmpty(queue)) {
        printf("Priority Queue is empty. Cannot delete element.\n");
        return;
    }

    // 将堆顶元素与队尾元素交换
    queue->data[0] = queue->data[queue->size - 1];
    queue->size--;

    // 对交换后的堆顶元素进行下沉操作,以维护堆的性质
    int i = 0;
    while (1) {
        int leftChild = 2 * i + 1;
        int rightChild = 2 * i + 2;
        int largest = i;

        if (leftChild < queue->size && queue->data[leftChild] > queue->data[largest]) {
            largest = leftChild;
        }

        if (rightChild < queue->size && queue->data[rightChild] > queue->data[largest]) {
            largest = rightChild;
        }

        if (largest != i) {
            int temp = queue->data[i];
            queue->data[i] = queue->data[largest];
            queue->data[largest] = temp;
            i = largest;
        } else {
            break;
        }
    }
}

// 销毁优先队列
void destroy(PriorityQueue *queue) {
    queue->size = 0;
}

int main() {
    PriorityQueue queue;
    initialize(&queue);

    // 插入元素到优先队列
    insert(&queue10);
    insert(&queue30);
    insert(&queue20);

    // 输出优先队列中的最大值
    printf("Max value: %d\n", findMax(&queue));

    // 删除优先队列中的最大值
    deleteMax(&queue);

    // 输出优先队列中的最大值
    printf("Max value: %d\n", findMax(&queue));

    // 销毁优先队列
    destroy(&queue);

    return 0;
}

这段代码实现了一个最大堆的优先队列。可以根据需要修改代码中的 MAX_SIZE 宏定义来调整队列的最大容量。在 main 函数中,我们先初始化一个优先队列 queue,然后插入一些元素,查找并输出最大值,删除最大值,最后销毁队列。


兄弟嵌入式
从入门到精通,学习并分享嵌入式软、硬件的知识。
 最新文章