前言
在生活中我们常常会遇到栈和队列的问题,比如放盘子、取盘子(类似栈)先进后出的集合,排队 (类似队列)先进先出的集合。这两种情况在.NET里面已经有相关的类库Stack和Queue,在这里不再 进行讨论,有兴趣的朋友可以百度一下这方面的资料。在这里主要讨论下优先队列,是在Queue基础上 的扩展。
1.优先队列
大家所知,队列是一种先进先出的数据结构。这种行为的效果就是会最先移除结构内最早进入的数 据项。然而,对于很多应用程序而言,需要一种可以把具有最高优先级的数据项最先移除的数据结构 ,即使这个数据项在结构中不是“最早进入的”一个。对于这类应用程序Queue有一种特殊 的情况,那就是优先队列。
许多应用程序在操作中都用到了优先队列。一个很好的实例就是在计算机操作系统内的进程处理。 某些进程可能有高于其他进程的优先级,比如打印机进程就有典型的低优先级。进程(或任务)通常 会根据优先级进行编号,Priority(优先级)为0的进程比Priority为20的任务具有更高的优先级。
通常会把存储在优先队列中的数据项作为键值对来构造,其中关键字就是指优先级别,而值则用来 识别数据项。例如,可以按照如下形式对一个操作系统进程进行定义:
struct Process
{
int priority;
string name;
}
我们不能把未修改的Queue对象用于优先队列。DeQueue方法在被调用时只会把队列中的第一个数据 项移除。但是,大家可以从Queue类派生出自己的优先队列类,同时覆盖DeQueue方法来实现自己的需 求。
我们把这个类称为PQueue。所有Queue的方法都可以照常使用,同时覆盖DeQueue方法来移除具有最 高优先级的数据项。为了不从队列前端移除数据项,首先需要把队列的数据项写入一个数组。然后遍 历整个数组从而找到具有最高优先级的数据项。最后,根据标记的数据项,就可以不考虑此标记数据 项的同时对队列进行重建。
具体类的代码如下:
public struct PQItem
{
public int Priority;
public string Name;
}
public class PQueue : Queue
{
public PQueue()
{
}
public override object Dequeue()
{
object[] items;
int min;
items = this.ToArray();
min = ((PQItem)items[0]).Priority;
for (int x = 1; x <= items.GetUpperBound (0); x++)
{
if (((PQItem)items[x]).Priority < min)
{
min = ((PQItem) items[x]).Priority;
}
}
this.Clear();
int tmp;
for (tmp = 0; tmp <= items.GetUpperBound (0); tmp++)
{
if (((PQItem)items [tmp]).Priority == min &&
((PQItem)items [tmp]).Name != "")
this.Enqueue (items[tmp]);
}
return base.Dequeue();
}
}