From my previous blog post can be seen, I am a queue enthusiasts, many do not necessarily need to use the queue implementation of the algorithm I will also use the queue implementation, mainly due to the consistency of the queue and the intuitive thinking of people.
Today I talk about the priority queue (priority_queue), in fact, its essence is a heap, I stripped of its implementation code from the STL, you can refer to.
First function in the header file <queue>, belong to the namespace STD, need to pay attention to when using.
There are two common ways to declare a queue:
std::p riority_queue<t> pq;std::p riority_queue<t, Std::vector<t>, Cmp> PQ;
The first implementation is more commonly used, and then I give the corresponding declarations in the STL, and then explain.
template<class _ty, class _container = Vector<_ty>, class _PR = less<typename _container::value_type> > class Priority_queue
As you can see, the default template has three parameters, the first is the priority queue processing class, the second parameter is characteristic, is the container that holds the priority queue. In fact, the priority queue is implemented by the related operations of the heap in this container + C language. This container is either a vector or a dequeue, because the latter is more powerful, and the performance is less than the vector, considering the packaging in the priority queue, the latter function does not play well, so the general choice of vector to do this container. The third parameter is important, support a comparison structure, default is less, by default, the first parameter will be selected to determine the class's < operator to do this comparison function.
Next began to pit dad, although the use of less structure, however, the queue of the order is greater first out! That is, this parameter is actually very proud, said that the meaning is if!cmp, then the first out, regardless of the purpose of this realization is what, we can only accept this realization. In fact, the third parameter here can be changed to greater, like this:
std::p riority_queue<t, Std::vector<t>, Greater<t>> PQ;
In general, if you are a custom class, simply overload < note the next direction, no one here trouble, this choice is basically in the use of the int class also want to small value first.
From the above analysis we also know that in order to allow the custom class to use the priority queue, we want to overload the less than sign.
class student{ int ID; Char name[]; BOOL gender; BOOL operator Const { return ID > a.id; }};
Take this example to say, we want to let the ID small first out, how to do, it will be very vainly disobey to this less than the symbol of the overloaded into the definition is actually greater than.
What if we don't use custom classes and use non-default methods to sort them? For example, in the Dijkstra, we certainly do not use the number of points to arrange, whether it is a positive or reverse order, we want to use points to the starting distance of this value to sort, how do we do? The attentive reader should have discovered the practice of customizing the comparison structure when reading my article about Dijkstra. The priority queue uses less than the structure by default, and the previous practice is to define a new smaller structure for our custom class to conform to the priority queue, and we can of course customize the comparison structure. The custom method and the use of the following, I directly use Dijkstra that code to illustrate:
intCost[max_v][max_v];intD[max_v], V, S;//Custom Priority Queue less comparison functionstructcmp{BOOL operator()(int&a,int&B)Const { //because the priority dequeue is determined as!cmp, the inverse definition implements the minimum value first returnD[a] >D[b]; }};voidDijkstra () {std::p riority_queue<int, std::vector<int, cmp>PQ; Pq.push (s); D[s]=0; while(!Pq.empty ()) { intTMP =pq.top ();p q.pop (); for(inti =0; I < v;++i) {if(D[i] > d[tmp] +Cost[tmp][i]) {D[i]= D[tmp] +Cost[tmp][i]; Pq.push (i); } } }}
The daily use of priority queues is sufficient to understand those above. Here is the implementation method of STL for all member functions of the priority queue, I hope you read the feeling of not having a face. c is the vector or other container that you declared.
voidPush (value_type&&_val) { //Insert element at beginningC.push_back (_std Move (_val)); Push_heap (C.begin (), C.end (), comp); } template<class... _valty>voidEmplace (_valty&&... _val) { //Insert element at beginningC.emplace_back (_STD forward<_valty>(_val) ...); Push_heap (C.begin (), C.end (), comp); } BOOLEmpty ()Const { //test if queue is empty return(C.empty ()); } size_type size ()Const { //return length of queue return(C.size ()); } const_reference Top ()Const { //return highest-priority element return(C.front ()); } voidPushConstvalue_type&_val) { //Insert value in priority orderC.push_back (_val); Push_heap (C.begin (), C.end (), comp); } voidpop () {//Erase highest-priority Elementpop_heap (C.begin (), C.end (), comp); C.pop_back (); }
On the priority queue (Priority_queue) in C + + STL