优先队列

优先队列故事引入

现实生活中,我们在排队干一件事情的时候,总要有个先来后到,但是如果其中一个人是vip,恐怕就可以后来居上了。因此,我们这里用优先队列来模拟这种现实生活中的情况。

优先队列原理

优先队列相比较于普通的队列,入队的顺序并没有发生变化,唯一不一样的是,出队的顺序是根据队列中元素的优先级(priopity)来判断的

优先队列源码实现

#include <iostream>
#define MAX_SIZE 12

using namespace std;

typedef int dataType;
/*********************
这里我选择采用链式存储的方法,
每一个元素包含了数据data,
优先级 priopiry以及指针域
指向下一个元素地址的指针next
***********************/
typedef struct _QNode {
	dataType data;
	int priority;
	_QNode* next;
	
}QNode;

typedef struct {
	int length;
	QNode* front;
	QNode* rear;
}PrQueue;
//初始化优先队列
bool init(PrQueue*& PQ) {
	if (!PQ) return false;
	PQ->front = PQ->rear = NULL;
	PQ->length = 0;
	return true;
}
//判断优先队列是否为空
bool isEmpty(PrQueue*& PQ) {
	if (!PQ) return false;
	if (PQ->front == NULL) return true;
	return false;
}
//判断优先队列是否为满
bool isFull(PrQueue*& PQ) {
	if (!PQ) return false;
	if (PQ->length == MAX_SIZE) return true;
	return false;
}
//入队
bool PqInsert(PrQueue*& PQ,dataType data,int priopity) {
	if (!PQ) return false;
	if (isFull(PQ)) {

		cout << "队列已满了!" << endl;
		return false; 
	}
	QNode* N = NULL;
	N = new QNode;
	N->data = data;
	N->priority = priopity;
	N->next = NULL;
	if (isEmpty(PQ)) {
		PQ->front = PQ->rear = N;
	}
	else {
		PQ->rear->next = N;
		PQ->rear = N;
	}
	PQ->length++;
	return true;
}
/**********************************************************************
************************************************************************
出队算法思路:
设置last和tmp一前一后来遍历整个优先队列,node指向优先级最大节点,因为遍历
双向队列过程中,last会移动,我们用node来记录这个优先级最大节点
设置一个二级指针prev用来指向node的上一个节点的next的地址,这里为什么要设置二级指针?
1.当队列中只有一个元素的时候,此时只有头节点跟一号节点,用二级指针可以直接修改
PQ中的front的值2.当队列中有多个元素的时候,此时prev用来放置node的上一个节点的next的地址,调用
*prev我们可以直接使node上一个节点的next值变为last里的next。
while循环直到tmp == NULL结束,也就是last指向最后一个节点结束
******************************************************************************
*******************************************************************************/
bool PqDelete(PrQueue*& PQ) {
	if (!PQ) return false;
	if (isEmpty(PQ)) return false;
	QNode** prev = NULL, *node = NULL;
	QNode* tmp = NULL, * last = NULL;
	prev = &(PQ->front);
	cout << "第一个节点的优先级是" << (*prev)->priority << endl;
	last = PQ->front;
	tmp = last->next;
	while (tmp) {
		if (tmp->priority > (*prev)->priority) {
			prev = &(last->next);
			node = last;
		}
		last = tmp;
		tmp = last->next;
	}
	tmp = *prev;
	*prev = (*prev)->next;
	delete tmp;
	PQ->length--;
	//删除的是头节点,而且是最后一个元素
	if (PQ->length == 0) {
		PQ->rear = NULL;
	}
	//删除的是尾部节点
	if (node&&node->next == NULL) {
		PQ->rear = node;
	}
	return 1;
}
//干掉优先队列
bool clearPq(PrQueue*& PQ) {
	if (!PQ) return false;
	if (isEmpty(PQ)) return true;
	QNode* N = PQ->front;
	QNode* tmp = NULL;
	while (N) {
		tmp = N;
		N = N->next;
		delete tmp;
	}
	PQ->front = PQ->rear = 0;
	PQ->length = 0;
	return true;
}
//遍历优先队列中所有元素
bool printPq(PrQueue*& PQ) {
	if (!PQ) return false;
	if (isEmpty(PQ)) {
		cout << "优先队列为空!无法打印东西哦." << endl;
		return false;
	}
	QNode* N = NULL;
	N = PQ->front;
	while (N) {
		cout << N->data << "\t" << "优先级:" << N->priority << endl;
		N = N->next;
	}
	return true;
}
上一篇:python爬虫学习笔记(十一)-数据提取之PyQuery的使用


下一篇:AtCoder Beginner Contest 184 题解