【学习记录】优先队列

优先队列可以快速找到最顶上的元素,可以是最小值也可以是最大值,但是其余元素并不能满足顺序排列
完整代码
.h文件

//
// Created by A on 2025/2/9.
//

#ifndef DEVP_PRIORITYQUEUE_H
#define DEVP_PRIORITYQUEUE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* 优先队列
*
* */
#define  MAXQUEUE_SIZE  64  //最大队列里64个元素


typedef struct {
    int priority; //优先级 据此来排序优先队列


}Queue_data;

typedef struct {
    Queue_data *elements; //队列元素
    int max_depth;      //最大深度
    int depth;      //目前的深度
}PriorityQueue;



PriorityQueue * createPriorityQueue(int maxdepth);

// 插入元素到优先队列
int priorityqueue_insert(PriorityQueue *pq, Queue_data value);

// 移除并返回最大值
int priorityqueue_extractMax(PriorityQueue *pq,Queue_data *retdata);

// 清理资源
void destroyPriorityQueue(PriorityQueue *pq);

//获取最尾的数据
int priorityqueue_getminvalue(PriorityQueue *pq,Queue_data *retdata);

//获取最尾的数据并删除最尾的数据
int priorityqueue_getminvalue_del(PriorityQueue *pq,Queue_data *retdata);

// 清理资源
void destroyPriorityQueue(PriorityQueue *pq);


#ifdef __cplusplus
}
#endif
#endif //DEVP_PRIORITYQUEUE_H

.c文件

//
// Created by A on 2025/2/9.
//
#include "priorityqueue.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
#include "stdlib.h"
PriorityQueue * createPriorityQueue(int maxdepth) {
    PriorityQueue *pq = (PriorityQueue*)malloc(sizeof(PriorityQueue));
    if(pq==NULL){
        return NULL;
    }
    pq->max_depth = maxdepth;
    pq->depth = 0;
    pq->elements = (Queue_data*)malloc(pq->max_depth * sizeof(Queue_data));
    memset(pq->elements,0,pq->max_depth * sizeof(Queue_data));
    if(pq->elements==NULL){
        free(pq);
        return NULL;
    }
    return pq;
}

// 堆上浮操作 从最尾插入了数据需要上浮
void heapifyUp(PriorityQueue *pq) {
    int index = pq->depth - 1; //插入的时候多加了1 排序的时候回退到有元素的位置
    while (index > 0) {
        int parentIndex = (index - 1) / 2; //此处不需要分奇数偶数,(3-1)/2=(4-1)/2=1
        if (pq->elements[parentIndex].priority <= pq->elements[index].priority) break;
        // 交换父节点和当前节点
        Queue_data temp = pq->elements[parentIndex];
        pq->elements[parentIndex] = pq->elements[index];
        pq->elements[index] = temp;
        index = parentIndex;
    }
}

// 插入元素到优先队列
int priorityqueue_insert(PriorityQueue *pq, Queue_data value) {
    if (pq->depth >= pq->max_depth) {
        // 容量不足
        return -1;
    }
    pq->elements[pq->depth] = value; //每次插入到队尾
    pq->depth++;
    heapifyUp(pq);//上浮,维持完全二叉树的性质
}

// 堆下沉操作 从顶上插入了数据需要下沉
void heapifyDown(PriorityQueue *pq) { //通常进行一次下沉操作后左右优先级就会排号
    int index = 0;
    while (1) {
        int leftChildIndex = 2 * index + 1;
        int rightChildIndex = 2 * index + 2;
        int largest = index;
        if (leftChildIndex < pq->depth && pq->elements[leftChildIndex].priority < pq->elements[largest].priority) { //上下
            largest = leftChildIndex;
        }
        if (rightChildIndex < pq->depth && pq->elements[rightChildIndex].priority < pq->elements[largest].priority) { //左右
            largest = rightChildIndex;
        }
        if (largest == index) break; //不能继续下沉,退出
        // 交换当前节点与最大子节点
        Queue_data temp = pq->elements[index];
        pq->elements[index] = pq->elements[largest];
        pq->elements[largest] = temp;
        index = largest;
    }
}

// 移除并返回最大值
int priorityqueue_extractMax(PriorityQueue *pq,Queue_data *retdata) {
    if (pq->depth <= 0||retdata==NULL){
        return -1;//深度错误
    }
    *retdata = pq->elements[0];
    pq->elements[0] = pq->elements[pq->depth - 1]; //最顶上的弹出后,最尾的顶在最顶上 然后下沉
    pq->depth--;
    heapifyDown(pq);
    return 0;
}
//获取最尾的数据
int priorityqueue_getminvalue(PriorityQueue *pq,Queue_data *retdata){
    if (pq->depth <= 0||retdata==NULL){
        return -1;//深度错误
    }
    *retdata = pq->elements[pq->depth - 1];
    return 0;
}
//获取最尾的数据并删除最尾的数据
int priorityqueue_getminvalue_del(PriorityQueue *pq,Queue_data *retdata){
    if (pq->depth <= 0||retdata==NULL){
        return -1;//深度错误
    }
    *retdata = pq->elements[pq->depth - 1];
    pq->depth--;
    return 0;
}
// 清理资源
void destroyPriorityQueue(PriorityQueue *pq) {
    free(pq->elements);
    free(pq);
}

#ifdef __cplusplus
}
#endif

实例

int main() {
    std::cout << "Hello, World!" << std::endl;
//    filedata_init();
    PriorityQueue* list =createPriorityQueue(64);


    Queue_data data={0};
    data.priority = 20;
    priorityqueue_insert(list,data);
    data.priority = 10;
    priorityqueue_insert(list,data);
    data.priority = 5;
    priorityqueue_insert(list,data);
    data.priority = 60;
    priorityqueue_insert(list,data);
    data.priority = 50;
    priorityqueue_insert(list,data);
    for (int i = 0; i < list->depth; i++) {
        printf("i= %d data =%d \n",i,list->elements[i].priority);
    }
    priorityqueue_extractMax(list,&data);
    printf("已取出 %d \n",data.priority);
    for (int i = 0; i < list->depth; i++) {
        printf("i= %d data =%d \n",i,list->elements[i].priority);
    }
    return 0;
}

现象
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值