优先队列可以快速找到最顶上的元素,可以是最小值也可以是最大值,但是其余元素并不能满足顺序排列
完整代码
.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;
}
现象