以前都用单链表实现优先队列,这次用堆实现优先队列。结构体组成如下
typedef struct _task {
int priority;
//其他属性省略
}task;
typedef task datatype;
typedef struct _priorityQueue{
datatype* arr;
int size;//当前已存储的元素个数
int capacity;//最大的存储容量
}priorityQueue;
我这里以降序优先队列为例,完整的代码实现如下:
#include<Windows.h>
#include<iostream>
using namespace std;
#define DEFAULT_CAPACITY 100
#define isLess(a,b) (pq.arr[a].priority<pq.arr[b].priority) //其中pq为优先队列的对象名,统一为pq
typedef struct _task {
int priority;
//其他属性省略
}task;
typedef task datatype;
typedef struct _priorityQueue{
datatype* arr;
int size;//当前已存储的元素个数
int capacity;//最大的存储容量
}priorityQueue;
bool initPriQueue(priorityQueue& pq, int* arr, int size);
void buildPriQueue(priorityQueue& pq);
void adjustPriQueueDown(priorityQueue& pq, int i);
bool insertPriQueue(priorityQueue& pq, int element);//新增加一个元素
bool popMax(priorityQueue& pq, int& value);
void destroyPriQueue(priorityQueue& pq);
int main() {
//01 建优先队列
int arr[] = { 4, 99, 23, 35, 23, 9, 1, 39, 21, 324, 231, 0 };
int size = sizeof(arr) / sizeof(arr[0]);
priorityQueue pq;
if (initPriQueue(pq, arr, size)) {
fprintf(stderr, "建优先队列成功!");
}
else {
fprintf(stderr, "建优先队列失败!");
exit(1);
}
cout << "遍历整个优先队列!" << endl;
for (int i = 0; i < pq.size; i++) {
cout << pq.arr[i].priority << " ";
}
//02 在优先队列的基础上增加元素,在优先队列的最后增加然后再调整
int element = 200;
insertPriQueue(pq, element);
cout << "遍历插入元素后的优先队列!" << endl;
for (int i = 0; i < pq.size; i++) {
cout << pq.arr[i].priority << " ";
}
//03 出列,从优先级最高的元素开始出列
cout << "优先队列的出列元素排列如下:" << endl;
int value;
while (popMax(pq, value)) {
cout << value << " ";
}
cout << endl;
destroyPriQueue(pq);
system("pause");
return 0;
}
bool initPriQueue(priorityQueue& pq, int* array, int size) {
int capacity = size > DEFAULT_CAPACITY ? size : DEFAULT_CAPACITY;
pq.arr =new datatype[capacity];
if (!pq.arr) return false;
pq.size = 0;
pq.capacity = capacity;
if (size > 0) {
//建堆的第一种方法
for (int i = 0; i < size; i++) {
memcpy(&pq.arr[i].priority, &array[i], sizeof(int));
}
pq.size = size;
buildPriQueue(pq);
//建堆的第二种方法
/*for (int i = 0; i < size; i++) {
insertPriQueue(heap, arr[i]);
}*/
}
return true;
}
void buildPriQueue(priorityQueue& pq) {
for (int i = (pq.size - 2) / 2; i >= 0; i--) {//从最后一个父节点开始
adjustPriQueueDown(pq, i);
}
}
void adjustPriQueueDown(priorityQueue& pq, int index) {
/*判断否存在大于当前节点的子节点,如果不存在 ,则堆本身是平衡的,
不需要调整;如果存在,则将最大的子节点与之交换,交换后,如果这个子节点还
有子节点,则要继续按照同样的步骤对这个子节点进行调整*/
datatype cur = pq.arr[index];//当前待调整的结点
int parent, child;
for (parent = index; (parent * 2 + 1) < pq.size; ) {
child = 2 * parent + 1;
if ((child + 1) < pq.size && isLess(child,child+1)) {
child++;
}
if (isLess(parent,child)) {
pq.arr[parent] = pq.arr[child];
pq.arr[child] = cur;
parent = child;
}
else {
break;
}
}
}
bool insertPriQueue(priorityQueue& pq, int element) {
if (pq.size == pq.capacity) {
cout << "栈空间耗尽!" << endl;
return false;
}
int index = pq.size;
int parent;
pq.arr[pq.size++].priority = element;
while (index > 0) {
parent = (index - 1) / 2;
if (parent < 0) break;
datatype tmp = pq.arr[parent];
if (isLess(parent,index)) {
pq.arr[parent] = pq.arr[index];
pq.arr[index] = tmp;
index = parent;
}
else {
break;
}
}
return true;
}
bool popMax(priorityQueue& pq, int& value) {
if (!pq.size) return false;
/*value = heap.arr[heap.size - 1];
heap.size--;*/
value = pq.arr[0].priority;
pq.arr[0] = pq.arr[--pq.size];//将尾结点赋值给头结点
adjustPriQueueDown(pq, 0);
return true;
}
void destroyPriQueue(priorityQueue& pq) {
if (pq.arr) delete[]pq.arr;
}