前情概述
本文主要用于理解优先级队列的实现细节。另外,记录自己的思考。
优先级队列的概念
首先优先级队列的概念脱胎于队列,队列有先进先出的概念,优先级队列则根据优先级的次序从队列中弹出元素。
优先队列的实现
优先队列的底层实现是堆,因为堆的插入时间复杂度为O(logN),所以优先级队列的入队操作的时间复杂度也是O(logN)。堆可以由动态数组实现的。
优先级队列中比较重要的两个操作是插入和删除。
如下简写了一个优先级队列的类:
class priority_queue{
public:
void insert();
void delete();
priority_queue(int n);
~priority_queue();
private:
int size; //优先级队列的大小
int capacity(); //优先级队列的容量大小
int * p; //动态数组,超出容量需要扩容
};
插入操作
插入操作,即插入到动态数组的末端,如果超过了数组的容量,那么就需要将数组的容量扩大一倍。如果对于堆的数据结构足够了解,插入操作即将要插入的元素放在队尾,然后按照优先级的比较顺序进行“上升”操作。在SGI STL的实现中,优先级队列被称之为容器配适器。根据SGI中对于优先级队列的定义:
template <class T, class Sequence = vector<T>,
class Compare = less<typename Sequence::value_type> >
我们发现只需要在声明的时候,填入模板中的类型、容器和比较函数,其中比较函数如果是less代表是最大堆,如果是greater代表是最小堆。当然还可以自己定义比较函数,比如如下的代码中就定义了最小堆:
struct node{
int idx;
int key;
node(int a=0, int b=0):idx(a), key(b){}
};
struct cmp{
bool operator()(node a, node b){
return a.key > b.key;
}
};
priority_queue<node, vector<node>, cmp> q;
删除操作
和堆的删除操作一样。不赘述。