Implementation framework of STL container adapter priority_queue

Source: Internet
Author: User

Note: This article is only for learning and communication. For more information, see the source!

In the previous article, we introduced the heap-related Operation algorithms in STL. Because the attention of heap is mainly used for sorting, we also know thatThe time complexity of heap sorting is O (nlogn), which is an unstable sorting algorithm.Using the heap data structure, we can quickly obtain the maximum (or minimum) k Number of a large data. At the same time, some problems related to heap algorithms are also raised in the previous article.

Question 1: Before calling the push_heap function to insert an element to the heap, we must first insert this element to the end of the underlying container, then, the push_heap internal upward adjustment can be called to adjust the new element to the appropriate position.

Question 2: When the pop_heap function is called to delete the heap top element, we only execute onePseudo-DeletionThat is, the element is not actually deleted from the underlying container, but is prevented from reaching the end of the container. to delete the element, you must call the pop_heap function, call the pop_back operation of the underlying container.

The above two problems clearly expose the shortcomings of the heap algorithm, that is, the operations of the heap algorithm are not neat, many of its actual operations need to be implemented by explicitly calling the functions of its underlying container. In fact, the heap algorithm can completely implement the insert and delete operations in a clean manner, which can be completed at a time. However, if you wrap these operations in the heap algorithm at a time, therefore, the heap sorting cannot be achieved. After all, our sorting aim is to obtain an array with sorted order, rather than a simple output. From this point of view, we can draw a conclusion that the heap algorithm is mainly used for heap sorting. We need to introduce another container adapter to make up for the deficiency of the heap algorithm.Priority_queueDoes not belong.

The underlying container of priority_queue must beContainers that provide random access to the iterator, SoThe vector and deque containers can be used as the underlying containers of priority_queue, but the list containers cannot.. The algorithms in priority_queue are further encapsulated based on heap algorithms and container operations. Before formally providing the implementation framework of priority_queue, I would like to explainSimilarities and differences between queue and priority_queue.

In the previous article, the implementation framework of the STL container adapter queue provides the properties and related operations of the container adapter queue. Now let's compare the similarities and differences between priority_queue and queque.

Similarities between priority_queue and queue

1. It is not a container, but a container adapter.

2. No iterator is provided, and element traversal is not supported (when elements are not completely popped up ).

3. Empty (), size (), pop (), and push (t) operations are provided.

4. All elements can only be popped up at the beginning of the team, but not at the end.

5. the header files using the two adapters are:# Include <queue>

Difference between priority_queue and queue

1. priority_queue is a priority queue. It can only get elements from the first queue, and the first element has the highest priority (this is not displayed), while the queue can only get elements from the first queue, you can also get elements at the end of the team. That is:Priority_queue only has the top () function, while queue has both the front () function and back () function..

2. The basic container of priority_queue must be able to provide a random access iterator, because the priority_queue algorithm mainly calls heap-related algorithms, and the iterators in heap-related algorithms are random access iterators.The base container of priority_queue can only be vector and deque., Cannot be list. The basic container of queue must provide the first delete operation pop_front, soThe basic container of queue cannot be vector, but deque and list..

Note:: The internal implementation of the pop operations of priority_queue and queue is different. The internal implementation of the pop operation of queue depends on the pop_front () function of its basic container. The pop operation of priority_queue consists of two operations: pop_heap () + The pop_back () of the underlying container. That is to say, the pop operation of priority_queue first exchanges the elements on the top of the heap with the end elements, and then performs the downward adjustment operation on the new heap top elements, finally, you can call the pop_back operation of the basic container to delete the elements with the highest priority.

The following is the implementation code and test code of priority_queue.

The implementation code is as follows:

# Include <iostream> # include <vector> // by default, vector is used as the underlying container # include <algorithm> // xxx_heap algorithm is used # include <functional> // The default function is less. <t> compare using namespace STD as a priority; template <class T, class sequence = vector <t>, class compare = less <typename sequence: value_type> // The third parameter can only be a function-like class, the object class priority_queue {public:/********* defines the public access attribute **************/typedef typename sequence :: value_type; // defines the element type typedef typename sequence: size_type; // defines the size type typedef typename sequence: Reference reference; // defines the reference type typedef typename sequence :: const_reference; // defines the common reference type protected: sequence C; // The sequential container compare CMP adopted at the underlying layer; // The comparison method of the underlying imitation functions public: priority_queue (): C () {}// No parameter constructor. Call the default constructor of the underlying container. Explicit priority_queue (const compare & X): C (), CMP (X) {}// Single-parameter constructor, modified with explicit to prevent implicit conversion from the form parameter type to the class type template <class inputiterator> // define the member template priority_queue (inputiterator first, inputiterator last): C (first, last) // call the range constructor of the underlying container and use the default comparison method {make_heap (C. begin (), C. end (), CMP); // create a heap using the real parameter range} template <class inputiterator> prioriry_queue (inputiterator first, inputiterator last, const compare & X): C (first, last), CMP (x) // call the range constructor of the underlying container and specify the comparison method {make_heap (C. begin (), C. end (), CMP); // heap creation function} void push (const value_type & X) // insert operation {C. push_back (x); // first place the element to be inserted at the end of the original heap push_heap (C. begin (), C. end (), CMP); // call to adjust up to remaintain the heap nature} void POP () // delete operation {pop_heap (C. begin (), C. end (), CMP); // first swap the heap top element with the last element, and then adjust the newly switched heap top element downward. pop_back (); // delete an element from the underlying dynamic array} const_reference top () // obtain the first element (the highest priority element) of the underlying container {return C. front ();} size_type size () const // return the number of elements in the current priority queue (equal to the size of the underlying container) {return C. size ();} bool empty () // judge whether the priority queue is empty {return C. empty ();}};

The test code is as follows:

Int main () {int arr [] = {3, 7, 2, 1, 4, 9, 2, 7}; priority_queue <int, vector <int>, greater <int> q (ARR, arr + sizeof (ARR)/sizeof (INT )); // The common pointer we usually use must be a random access iterator cout <"------------ the element before the pressure queue is ----------" <Endl; copy (ARR, arr + sizeof (ARR)/sizeof (INT), ostream_iterator <int> (cout, ""); cout <Endl; // less <t> indicates that the bottom layer is a large top stack, and greater <t> indicates that the bottom layer is a small top stack, the heap type is exactly the opposite of the word meaning./********** perform operations on the initial priority queue *********/cout <"------------ initial operation -------------- "<en DL; cout <"queue size:" <q. size () <Endl; cout <"first element:" <q. top () <Endl; // The highest priority of the shoushou element is/********* after the top element is out of the queue, ***********/Q. pop (); cout <"------------- -----------" <Endl; cout <"queue size:" <q. size () <Endl; cout <"first element:" <q. top () <Endl;/******* add an element to the queue-3 **************/Q. push (-3); cout <"------------ press-3 to the queue and then -----------" <Endl; cout <"queue size:" <q. size () <Endl; cout <"first element:" <q. top () <Endl;/***** output the existing elements in the queue in sequence ******/C Out <"----------- output existing elements in the queue in sequence -----" <Endl; while (! Q. empty () // because the queue is not a container, it is only a container adapter without an iterator and cannot provide a single traversal operation {cout <q. top () <"; // only the first access is displayed, and then the access is displayed in order to access all elements. pop () ;}cout <Endl; return 0 ;}

The running result is as follows:


References

[1] STL source code analysis Hou Jie

[2] C ++ primer 4th

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.