STL中priority queue的使用注意事項

2021-06-18 21:52:38 字數 1506 閱讀 3604

今天在使用priority_queue寫乙個演算法的時候,總是報heap異常,查了很久,才知道原因。

我們知道優先順序佇列的底層是用heap來實現的,每次push和pop操作後,都會呼叫heapify來調整最大堆得結構。

我們先來看看priority_queue的宣告:

priority_queue, vector>, cmp> pq;

這是我使用的乙個優先順序佇列,佇列裡每個元素都是乙個stack,第乙個引數就是元素的型別,第二個引數是指定優先順序佇列使用什麼容器,如果不指定,預設就是vector。下面是priority_queue的模板宣告:

template,

class _pr = less>

我們可以看到,第三個模板引數就是比較函式了,指定優先順序佇列中的比較方法。這個比較方法必須是strick weak order的,不知道的同學可以上網查一查。這個非常重要,以後每次調整heap前,都會檢查現有佇列是否是strick weak order。下面是我的比較方法:

struct cmp

};

如果你優先順序佇列中的元素是乙個容器的話(比如vector,stack,queue之類的),就需要特別注意了,如果你要向優先順序佇列中的元素(這個元素是乙個容器)中插入元素的話,我的建議是先把該容器整個pop出來,然後更新該容器,再push進去,**如下:

activity a(s[i], f[i]);

stackst = pq.top();

st.push(a);

pq.pop();

pq.push(st);

你會想,這樣寫會更簡便啊:

activity a(s[i], f[i]);

pq.top().push(a);

這會引發乙個嚴重的錯誤,因為你插入的元素並沒有呼叫priority_queue的push操作,所以並不會更新其佇列的順序,這樣,佇列中的順序就可能已經錯亂了,你會說:下次呼叫push的時候不就會重新調整好heap的順序麼,下面我們來看priority_queue的原始碼:

void push(value_type&& _val)

我們在進入push_heap這個agorithm中的演算法(注意這是乙個通用演算法):

templateinline

void push_heap(_ranit _first, _ranit _last, _pr _pred)

}

注意,在push_heap之前,他會進行_debug_heap_pred檢查,就是檢查堆中的元素是否按照你給定的順序進行排序的,如果不是,直接返回乙個異常。所以,我們在想priority_queue中的容器中插入資料時,先pop,再修改,最後push。不會產生上述問題。

STL容器 優先佇列priority queue

priority queue顧名思義,是乙個具有權值概念的queue,它和queue一樣允許加入新元素 移除舊元素等功能。由於這是乙個queue,所以只允許在底部加入元素,從頂部取出元素。但優先佇列帶有權值概念,其內的元素自動按照元素的權值排序。權值最高者排在最前面。stl的priority que...

STL初步 優先佇列Priority queue

這個優先到底是如何優先?和普通佇列區別在哪?priority queue type,container,functional priority queue,less q priority queue,less a q priority queue,less b 優先佇列中沒有迭代器 也沒有clear...

stl原始碼分析之priority queue

前面兩篇介紹了gcc4.8的vector和list的原始碼實現,這是stl最常用了兩種序列式容器。除了容器之外,stl還提供了一種借助容器實現特殊操作的元件,謂之介面卡,比如stack,queue,priority queue等,本文就介紹gcc4.8的priority queue的原始碼實現。顧名...