优先级队列——PriorityQueue

优先级队列

提起优先级队列,首先想到了操作系统中的作业调度算法的相关应用,还有就是解决 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;
        }

猜你喜欢

转载自blog.csdn.net/sinat_31508159/article/details/50650359