代码改变世界

队列的应用:优先队列

2017-08-05 19:43  tlnshuju  阅读(283)  评论(0编辑  收藏  举报

优选队列:假设我们给每一个元素都分配一个数字来标记其优先级。最好还是设较小的数字具有较高的优先级,这样我们就能够在一个集合中訪问优先级最高的元素并对其进行查找和删除操作了。

优先队列(priority queue)是0个或多个元素的集合,每一个元素都有一个优先权,对优先级队列运行的操作有(1)查找(2)插入一个新元素(3)删除 普通情况下,查找操作用来搜索优先权最大的元素。删除操作用来删除该元素 。对于优先权同样的元素,可按先进先出次序处理或按随意优先权进行。


以上是网上常见的对优先级队列的描写叙述。偷个懒,直接抄过来。主要是它描写叙述的非常清楚。

重要的是优先队列与普通队列的差别:

  1. 删除时。总是删除优先级最大的,并不是仅仅是普通的队头出队。
  2. 普通队列不存在查找操作。优先级队列的查找,一定是查找优先级最大的。
以下我们使用顺序存储结构实现优先级队列,其他的细节看代码:
类定义和类实现
#include<iostream>
#include<iomanip>
using namespace std;
const int MAX = 10;
typedef struct node    //priority queue node
{
	int no;        //任务编号
	int priority;   //优先级
}PQNode;
class PQueue    //优先队列类
{
private:
	PQNode *base;
	int size;     //队列大小
public:
	//构造函数 
	PQueue();
	//析构函数 
	~PQueue();
	//获取队列大小 
	int getSize()
	{return size;}  
	//推断队列是否为空 
	bool empty()
	{return size == 0;}
	//清空
	void clear()
	{size = 0;}
	//重载运算符<
	bool friend operator<(PQNode node1, PQNode node2);
	//入队
	bool push(PQNode);
	//出队
	bool pop(PQNode&);
	//查找
	bool find(PQNode&);
	//遍历 
	void queueTraverse(); 
};
PQueue::PQueue()
{
	base = new PQNode[MAX];
	size = 0;
}
PQueue::~PQueue()
{
	delete[]base;
}
bool operator<(PQNode node1, PQNode node2)
{
	return node1.priority < node2.priority;
}
bool PQueue::push(PQNode node)
{
	int i;
	for (i=0; i < size; i++)
	{
		if (node.no == base[i].no)  //对于已存在的任务编号更新优先级 
		{
			base[i].priority = node.priority;
			break;
		}
	}
	if (i < size || (i == size && size < MAX))
	{
		if (i == size)
		base[size++] = node;
		return true;
	}
	//已无空间存放新节点 
	return false;
}
bool PQueue::pop(PQNode &node)
{
	if (size == 0)
		return false;
	int index = 0;
	for (int i = 1; i < size; i++)
	{
		if (base[i] < base[index])  //若是没有重载<。则这里必须写成base[i].priority<base[index].priority
			index = i;
	}
	node = base[index];
	/*
	出队后,index位置该怎样填补?
	方法多种:
	一、index后的元素依次前移
	二、直接用最后一个元素填到index位置
	建议使用第一种 
	*/
	size--;
	for (int i = index; i < size; i++)
		base[i] = base[i + 1];
	return true;
}
bool PQueue::find(PQNode &node)
{
	if (size == 0)
		return false;
	int index = 0;
	for (int i = 1; i < size; i++)
	{
		if (base[i] < base[index])
			index = i;
	}
	node = base[index];
	return true;
}
void PQueue::queueTraverse()
{
	if(!empty())
	{
		int i=0;
		cout<<"编号"<<" "<<"优先级"<<endl;
		while (i < size)
		{
			cout<<setw(4)<<base[i].no<<setw(4)<<base[i].priority<<endl;
			i++;
		}
	}
}
主函数
int main()
{
	cout<<"******优先级队列演练******"<<endl;
	PQueue pqueue;
	cout<<"队列眼下的状态是";
	pqueue.empty()?cout<<"空!"<<endl:cout<<"非空!"<<endl;
	PQNode node;
	cout<<"输入任务号和优先级(一组一行),输入0 0结束"<<endl;
	while(cin>>node.no>>node.priority && node.no && node.priority)
		pqueue.push(node);
	cout<<"打印队列"<<endl;
	pqueue.queueTraverse();
	cout.setf(ios::left);
	cout<<"查找优先级最高的"<<endl;
	pqueue.find(node)?

cout<<"编号是"<<setw(4)<<node.no<<"优先级是"<<setw(4)<<node.priority<<endl:cout<<"空队列。无法查找。"<<endl; cout<<"队列清空"<<endl; pqueue.clear(); cout<<"队列眼下的状态是"; pqueue.empty()?cout<<"空!

"<<endl:cout<<"非空!

"<<endl; system("pause"); return 0; }

执行:


完整代码下载:优先队列

专栏文件夹看这里: