优先级队列——PriorityQueue

来源:互联网 发布:数控铣床编程动漫图案 编辑:程序博客网 时间:2024/06/05 04:56

优先级队列

提起优先级队列,首先想到了操作系统中的作业调度算法的相关应用,还有就是解决 Top n (一个集合中最大或最小的n的元素)之类的问题。

操作系统中的作业调度有短作业优先(SJF)、先来先服务(FCFS)、时间片轮转法、优先级法等。

其中,优先级法可以近似看成是利用了优先级队列,根据作业的优先级来从作业队列中选择下一个将要执行的作业。而Top n之类的问题也是这样。优先级队列可以用 * 堆 *这一数据结构来描述并解决,这样的编码和计算效率都很高。

优先级队列操作一个初始为空的元素集合称为S。
  • insert——在集合中插入一个新元素
  • extractmin——删除集合中的最小元素(或最大元素)

优先级队列的堆实现使用了具有堆性质的数组x[1…n]表示n元集合。x在C或C++中声明为x[maxsize + 1]从x[1]开始使用,通过复制n = 0 将集合初始化为空,每插入一个新元素时,n就加1,并将元素放在x[n]处。

下面是插入元素的伪代码:

void insert(t)    if n >= maxsize        error    n++    x[n] = t    Heapify(x)//调整数组x,使之具有最小堆的性质

extractmin查找并删除集合中的最小元素,然后使集合重新具有堆的性质。由于开始初始化成了一个最小堆,所以最小元素位于x[1]处,集合中剩下的n-1个元素位于x[2…n-1]中。首先,将x[n]移到x[1]处,将n减1;然后将x[1…n-1]重新调整为具有最小堆性质的数组即可。

下面是extractmin函数伪代码:

int extractmin()    if n < 1        error    t = x[1]    x[1] = x[n]    n--    Heapify(x)//调整数组x,使之重新具有最小堆的性质

最后是优先级队列的完整C++实现:

template <class T>class PriorityQueue{    private:        int n, maxsize;        T *x;        void swap(int i, int j)        {            T temp = x[i];            x[i] = x[j];            x[j] = temp;        }     public:        PriorityQueue(int m)//优先级队列构造函数        {            maxsize = m;            x = new T[maxsize + 1];            n = 0;        }        ~PriorityQueue(){}//析构函数        void insert(T t)        {            int i, p;            x[++n] = t;            for(i = n; i > 1 && x[p = i / 2] > x[i]; i =p)                swap(p, i);        }        T extractmin()        {            int x, c;            T temp = x[1];            x[1] = x[n--];            for(i = 1; (c = 2 * i) <= n; i = c)            {                if(c + 1 <= n && x[c + 1] < x[c])//选取子结点中较小的一个                    c++;                if(x[i] < x[c])                    break;                swap(c, i);            }            return temp;        }
0 0
原创粉丝点击