数据结构与算法系列(4)优先队列

前言

在生活中我们常常会遇到栈和队列的问题,比如放盘子、取盘子(类似栈)先进后出的集合,排队 (类似队列)先进先出的集合。这两种情况在.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();

       }

}

时间: 2024-08-22 15:24:08

数据结构与算法系列(4)优先队列的相关文章

数据结构与算法系列(1)时间测试

前言 好久都把数据结构和算法的东西忘完了,最近想重温下这些知识.因此就写了<<数据结构与 算法系列>的文章,希望能和大家共同学习,共同探讨这方面的知识.希望大家多多指异. 1.时间测试 由于本部分内容采用了一种实用的方法来分析数据结构与算法检测,所以在这里避开了使用大O分 析法,而采用运行简单基准测试的方法来代替.这种测试将会说明运行一段代码需要多少秒数(或者 无论什么时间单位). 基准法测试是使用时间测试的方法来衡量运行完整算法所花费的时间长度.如同科学一样,基准测 试也像是一门艺术,

数据结构与算法系列(2)基础排序算法

前言 在计算机中实现存储数据最普遍的两种操作就是排序和查找.这是从计算机产业初始就已经确认的 了.这意味着排序和查找也是计算机科学领域最值得研究的两种操作.本书提到的许 多数据结构的主要设计目的就是为了使排序和/或查找更加简单,同时也是为了数据在结构内的存 储更加有效. 本章会介绍有关数据排序和查找的基础算法.这些算法仅依赖数组作为数据结构,而且所采用的 "高级"编程技术只是递归.本章还介绍了用来非正式分析不同算法之间速度与效率的方 法,此方法贯穿全书. 1.排序算法 人们在日常生活中

数据结构与算法系列(3)基础查找算法

前言 数据查找是基础的计算机编程工作,而且人们对它的研究已经很多年了.在本部分只会看到查找问 题的一个内容,即根据给定的数值在一个列表(数组)中进行查找. 有两种对列表内数据进行查找的方法:顺序查找和二驻查找.当数据项在列表内随机排列的时候可 以使用顺序查找,而当数据项在列表内有序排列的时候则会用到二叉查找. 1.顺序查找算法 最突出的查找类型就是从记录集的开始处顺次遍历每条记录,直到找到所需要的记录或者是到达数 据集的末尾.这就是所谓的顺序查找. 顺序查找(也称为线性查找)是非常容易实现的.从

JavaScript数据结构与算法之集合(Set)_基础知识

集合(Set) 说起集合,就想起刚进高中时,数学第一课讲的就是集合.因此在学习集合这种数据结构时,倍感亲切. 集合的基本性质有一条: 集合中元素是不重复的.因为这种性质,所以我们选用了对象来作为集合的容器,而非数组. 虽然数组也能做到所有不重复,但终究过于繁琐,不如集合. 集合的操作 集合的基本操作有交集.并集.差集等.这儿我们介绍JavaScipt集合中交集.并集.差集的实现. JavaScipt中集合的实现 首先,创建一个构造函数. /** * 集合的构造函数 */ function Set

数据结构与算法(C#实现)系列---演示篇(一)

数据|数据结构|算法 数据结构与算法(C#实现)系列---演示篇(一) Heavenkiller(原创) 这一篇主要是针对以后各篇的数据类型进行一个实质性的演示.因此希望大家具体看了各种数据结构的分析之后再看这篇. 主要包括如下几个方面的演示: 1. 堆栈. 演示了一个利用堆栈作的RPN计算器 2. 排序表.演示了一个利用排序表做的多项式表达式的加法运算 3. 广义树.演示了深度遍历和广度遍历 4. N叉树.演示了N叉树的生成插入删除等基本操作 5. 表达式树.演示了一个用二叉树和堆栈做的可以将

数据结构与算法(C#实现)系列---N叉树(二)

数据|数据结构|算法 数据结构与算法(C#实现)系列---N叉树(二) Heavenkiller(原创) public override uint Degree { get { return this.degree; } } //------------------------------------------------------------------------------------- //只用于空树结点 public virtual void AttachKey(object _o

数据结构与算法(C#实现)系列---演示篇(二)

数据|数据结构|算法 数据结构与算法(C#实现)系列---演示篇(二) Heavenkiller(原创) public static void ShowGeneralTree_travel() { IEnumerator tmpIEnum; Tree.TraversalType travelType=0; //---------------------提示---------------------------- Console.WriteLine("please choose a the No.

数据结构与算法(C#实现)系列---演示篇(三)

数据|数据结构|算法 数据结构与算法(C#实现)系列---树(二) Heavenkiller(原创) public class InOrder:IPrePostVisitor { private IVisitor visitor; public InOrder(IVisitor _vis){visitor=_vis;} #region IPrePostVisitor 成员 public void PreVisit(object _obj) { // TODO: 添加 InOrder.PreVis

数据结构与算法(C#实现)系列---广义树(一)

数据|数据结构|算法 数据结构与算法(C#实现)系列---广义树(一) Heavenkiller(原创) 广义树和基本树的主要区别就是有任意的度 using System; using System.Collections; namespace DataStructure { /// <summary> /// GeneralTree 的摘要说明. /// general tree is a tree which has a arbitrary degree and no empty tree