优先级队列(priorityqueue)是0个或多个元素的集合,每个元素都有一个优先权,对于优先权相同的元素,可按先进先出次序处理或按任意优先权进行。
头文件:
//AfxStd.h #include<stdio.h> #include<stdlib.h> #include<assert.h>
//apqueue.h #ifndef APQUEUE_H #define APQUEUE_H typedef int ElemType; const int MaxPQSize = 50; typedef struct PriorityQueue { ElemType *data; int maxsize; int cursize; }PQueue; void InitQueue(PQueue &pq); //初始化优先级队列 void DestroyQueue(PQueue &pq); //摧毁优先级队列 void ClearQueue(PQueue &pq); //清空优先级队列 int QueueLength(PQueue &pq); //测量队列长度 bool QueueEmpty(PQueue &pq); //判断队列是否为空 bool QueueFull(PQueue &pq); //判断队列是否为满 bool InsertQueue_ar(PQueue &pq, ElemType *par, int n); //向队列插入一个数组 bool DeQueue(PQueue &pq, ElemType &item); //删除元素 bool EnQueue(PQueue &pq, ElemType item); //元素入队 void Swap(ElemType &a, ElemType &b); //交换元素的值 void FilterUp(ElemType *pAr, int start); //向上调整,结束位置默认是根结点 void FilterDown(ElemType *pAr, int start, int end); //向下调整 void MakeHeap(ElemType *pAr, int n); //构造最小堆 #endif //
源文件:
//AfxStd.cpp #include"AfxStd.h"
#include"AfxStd.h" #include"apqueue.h" void InitQueue(PQueue &pq) //初始化优先级队列 { pq.cursize = 0; pq.maxsize = MaxPQSize; pq.data = (ElemType *)malloc(sizeof(ElemType)*pq.maxsize); if (NULL == pq.data) { exit(1); } } void DestroyQueue(PQueue &pq) //摧毁优先级队列 { free(pq.data); pq.data = NULL; pq.maxsize = pq.cursize = 0; } void ClearQueue(PQueue &pq) //清空优先级队列 { pq.cursize = 0; //空间可以再次使用 } int QueueLength(PQueue &pq) //测量队列长度 { return pq.cursize; } bool QueueEmpty(PQueue &pq) //判断队列是否为空 { return QueueLength(pq) == 0; } bool QueueFull(PQueue &pq) //判断队列是否为满 { return QueueLength(pq) == MaxPQSize; } bool InsertQueue_ar(PQueue &pq, ElemType *par,int n)//向队列插入一个数组 { if (par == NULL || n < 1)return false; int j = pq.cursize; //插入元素的位置 for (int i = 0; i < n; ++i) { pq.data[j++] = par[i]; } pq.cursize += n; MakeHeap(pq.data, pq.cursize); return true; } bool DeQueue(PQueue &pq, ElemType &item) //删除队首元素 { if (QueueEmpty(pq))return false; item = pq.data[0]; pq.data[0] = pq.data[pq.cursize - 1]; pq.cursize -= 1; //元素个数少1 FilterDown(pq.data, 0, pq.cursize - 1); } bool EnQueue(PQueue &pq,ElemType item) //元素入队,数组已经确认是最小堆 { if (QueueFull(pq))return false; pq.data[pq.cursize] = item; pq.cursize += 1; FilterUp(pq.data, pq.cursize - 1); return true; } void Swap(ElemType &a, ElemType &b) //交换元素的值 { ElemType tmp = a; a = b; b = tmp; } /***************************************************************** *函数名:FilterUp *函数功能描述:将数组从下标为start开始,向上调整为最小堆 *函数参数:pAr-数组指针,start-调整的开始位置,end-调整的结束位置 *函数返回值:无返回值 *作者:王赋睿小胖子 *函数创建日期:2018.6.12 *函数修改日期:尚未修改 *修改人:尚未修改 *修改原因:尚未修改 *版本:1.0 *历史版本:无 *****************************************************************/ void FilterUp(ElemType *pAr, int start) //向上调整,结束位置默认是根结点 { assert(pAr != NULL); //防止对空指针进行操作 assert(start >= 0 ); //下标合法性检查 int j = start; // int i = (j - 1) / 2; ElemType tmp = pAr[j]; while (j > 0) { if (pAr[i] < tmp)break; // pAr[j] = pAr[i]; j = i; i= (j - 1) / 2; } pAr[j] = tmp; } void FilterDown(ElemType *pAr, int start, int end)//将下标在start之后都调整为最小堆 { assert(pAr != NULL); //防止对空指针进行操作 assert(start >= 0 ); //下标合法性检查 int i = start; //root int j = i * 2 + 1; //leftchild ElemType tmp = pAr[i]; while (j<=end) { if (j<end && pAr[j]>pAr[j + 1])j += 1; if (tmp < pAr[j]) break; pAr[i] = pAr[j]; i = j; j = 2 * i + 1; } pAr[i] = tmp; //放到合适的位置中去 } void MakeHeap(ElemType *pAr, int n) { assert(pAr != NULL); assert(n >= 1); int end = n - 1; int pos = (end - 1) / 2; //最后一个分支结点 while (pos >= 0) { FilterDown(pAr, pos, end); --pos; } }
//TestApQueue.cpp #include"AfxStd.h" #include"apqueue.h" int main() { ElemType ar[] = { 45,78,12,34,90,56,8,18 }; int n = sizeof(ar) / sizeof(ElemType); PQueue pq; InitQueue(pq); for (int i = 0; i < n; ++i) { EnQueue(pq, ar[i]); } int x; while (!QueueEmpty(pq)) { DeQueue(pq, x); printf("%-4d", x); } DestroyQueue(pq); return 0; }