1. Significance of the index priority queue
The index priority queue is a relatively abstract concept, which is a priority queue and index, what is the index used for?
In the normal queue, we can only access the queue header element, the entire queue of elements we are unable to access. So for the elements in these queues, if we have a mapping to know which of the M elements in the queue corresponds to which of our first priority queue we put all the elements, wouldn't it be much easier to use it?
We know that in a priority queue, the order in which an element is added to the queue is not fixed and may be floating or sinking. So how do we know where we're joining this element of the queue, exactly where it's in the queue?
This is the purpose of the index priority queue. it uses an indexed array to hold the position of an element in the priority queue .
For example:
// The value of the first element of the index priority queue is J // Well, we need this element J in the priority queue position is I
Thus, when we need to use this element J, we can directly find the position of J is the first I of the priority queue.
2. Actual application of the index priority queue
(1) from the above, it seems that we know that the index is of no practical use, is it true?
Consider the following situation, such as Li Lei test the class first, Han Meimei exam second. We ranked the top 40 of the class in the priority queue. But when the review, suddenly found Han Meimei score less 10 points, plus 10 points should she is the first. So, if we don't have this index, how do we change the priority queue we've formed?
Some people may say, very simple ah, put Li Lei and Han Meimei out of the queue, and then change the score, rejoin the queue.
OK, so, if Han Meimei score is wrong, she is the 39th person in the class? Do you want to get the scores of 39 people back in the queue and rejoin? This cost seems a bit high.
Further, what if it's a 4,000-person queue? What if the results of 1000 people were all wrong? We're going to regenerate this queue 1000 times?
This is where the index priority queue comes in. if Han Meimei's score is wrong, we know from the index that she is the second in the priority queue, then we directly modify her performance, and then float or sink on it, to pay a very small price.
(2) Further, if you want to queue up according to the results, then please parents on stage to teach the experience of tutoring? How do we know who is the parent of everyone?
At this point, we then use an array key[], which preserves the name correspondence between each person and the parent. In this way, is there a greater usefulness of an index?
Together, we get the third part of the index priority queue INDEXEDPQ implementation.
3. API and implementation of the index priority queue
In many applications, it is necessary to allow use cases to refer to elements that have entered a finite queue. An easy way to do this is that the use case already has multiple elements with a total of N, and may also use multiple (parallel) arrays (Parallel array) to store information about these elements. At this point, other unrelated use case codes may already be referencing these elements using an integer index. These considerations lead us to design the following table.
A good way to understand this data structure is to think of it as an array that can quickly access the smallest element in it. In fact it's even better-it can quickly access the smallest element in a particular sub-set of an array (meaning all the inserted elements). In other words, the INDEXMINPQ priority queue named PQ can be seen as a representation of a subset of the elements in array pq[0..n-1]. The Pq.insert (k, item) is considered as adding K to this subset and making pq[k] = Item, Pq.change (k, item) means pq[k] = Item. These two operations do not alter the data structure on which other operations depend, the most important being delmin () (deleting the smallest element and returning its index) and change (changing the index of an element in the data structure-that is, pq[i] = Item). These operations are important in many applications and rely on references to elements (indexes). In general, when a heap changes, we restore the heap's order by sinking (when the element is reduced) or by moving (when the element is larger). In these operations, we can find the element with an index. Being able to locate any element in the heap also allows us to add a delete () operation to the API.
Proposition Q (cont.). In an index-priority queue of size n, the number of comparisons required to insert an element (insert), change the priority (changes), delete, and delete the maximum small element (remove the minimum) is proportional to the logn (such as the following table)
Prove. It is easy to get this conclusion from the code that it is known that all paths in the heap are the longest of ~lgn.
Operation |
Order of magnitude of the number of comparisons |
Insert () |
Logn |
Change () |
Logn |
Contains () |
1 |
Delete () |
Logn |
Min () |
1 |
Minindex () |
1 |
Delmin |
Logn |
The following is a Java version Indexmaxpq.java of the index priority queue that is implemented in the ALG4 book to find the largest element.
The principle and implementation of index priority queue-indexedprirotyqueue (source code)