今天在使用priority_queue写一个算法的时候,总是报heap异常,查了很久,才知道原因。
我们知道优先级队列的底层是用heap来实现的,每次push和pop操作后,都会调用heapify来调整最大堆得结构。
我们先来看看priority_queue的声明:
priority_queue<stack<Activity>, vector<stack<Activity>>, cmp> pq;
这是我使用的一个优先级队列,队列里每个元素都是一个stack,第一个参数就是元素的类型,第二个参数是指定优先级队列使用什么容器,如果不指定,默认就是vector。下面是priority_queue的模板声明:
template<class _Ty, class _Container = vector<_Ty>, class _Pr = less<typename _Container::value_type> >
我们可以看到,第三个模板参数就是比较函数了,指定优先级队列中的比较方法。这个比较方法必须是strick weak order的,不知道的同学可以上网查一查。这个非常重要,以后每次调整heap前,都会检查现有队列是否是strick weak order。下面是我的比较方法:
struct cmp { bool operator()(stack<Activity> &q1, stack<Activity> &q2) { if(q1.top().start < q2.top().start) return true; return false; } };
Activity a(s[i], f[i]); stack<Activity> st = pq.top(); st.push(a); pq.pop(); pq.push(st);
Activity a(s[i], f[i]); pq.top().push(a);
void push(value_type&& _Val) { // insert element at beginning c.push_back(_STD move(_Val)); push_heap(c.begin(), c.end(), comp); }
template<class _RanIt, class _Pr> inline void push_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { // push *(_Last - 1) onto heap at [_First, _Last - 1), using _Pred _DEBUG_RANGE(_First, _Last); _DEBUG_POINTER(_Pred); if (_First != _Last) { // check and push to nontrivial heap --_Last; _DEBUG_HEAP_PRED(_First, _Last, _Pred); _Push_heap_0(_Unchecked(_First), _Unchecked(_Last), _Pred, _Dist_type(_First), _Val_type(_First)); } }