We can turn any priority queue into a sort method. Inserts all the elements into a priority queue that finds the smallest element, and then repeats the action of deleting the smallest element to delete them sequentially. Priority queues implemented with unordered arrays doing this is equivalent to making an insertion sort. What sort of order is this equivalent to using a heap-based priority queue? A new sort of method! Let's use the heap to implement a classic and elegant sorting algorithm-heap ordering.
Heap sorting can be divided into two stages. In the construction phase of the heap, we reorganize the original array into a heap, and then in the sinking sort phase, we remove all the elements from the heap in descending order and get the sorted results. In order to sort the need, we no longer hide the specific representation of the priority queue and will use the swim () and sink () operations directly. This allows us to sort the array itself as a heap, so we don't need any extra space.
1. Structure of the heap
How hard is it to construct a heap from n given elements? We can of course complete this task in a time proportional to the nlogn, simply traversing the array from left to right, using swim () to ensure that all elements on the left side of the scan pointer are already a fully ordered tree, just like inserting elements into the priority queue consecutively. A smarter and more efficient approach is to construct the sub-heap from right to left using the sink () function. Each location of the array is already the root node of a sub-heap, and sink () also applies to these sub-heaps. If the two sub-nodes of a node are already heaps, calling sink () on that node can turn them into a heap. This process will build up the order of the heap in a recursive manner. At the beginning we only need to scan half the elements in the array, because we can skip the sub-heap of size 1. Finally we call the sink () method on position 1, and the scan ends.
proposition: The heap is constructed from n elements with a sinking operation requiring less than 2N comparisons and less than n interchanges.
Proof: Observation shows that the heap processed in the construction process is smaller. For example, to construct a heap of 127 elements, we will handle 32 heaps of size 3, 16 heaps with a size of 7, 8 heaps of 15 size, 4 heaps of 31 size, 2 heaps of 63 size, and 1 heaps of 127 sizes, so (worst case) you need 32*1+16*2+8*3+4* 4+2*5+1*6=120 times (twice times the comparison).
2. Specific algorithms
/** * algorithm 2.7 heap sort * Created by Huazhou on 2015/11/23. */public class Heap extends Model {public void sort (comparable[] pq) {int N = pq.length; for (int k = N/2; k >= 1; k--) Sink (PQ, K, N); while (N > 1) {exch (PQ, 1, n--); Sink (PQ, 1, N); }} private void Sink (comparable[] PQ, int k, int N) {while (2*k <= N) {int j = 2*k; if (J < N && Less (PQ, J, J+1) J + +; if (!less (PQ, K, J)) break; Exch (PQ, K, J); K = J; }} private Boolean less (comparable[] PQ, int i, int j) {return Pq[i-1].compareto (Pq[j-1]) < 0; } protected void Exch (comparable[] PQ, int i, int j) {Comparable swap = pq[i-1]; PQ[I-1] = pq[j-1]; PQ[J-1] = swap; }}
This code uses the sink () method to sort the elements of a[1] to A[n] (sink () has been modified to a[] and N as arguments). The For loop constructs the heap, and then the while loop swaps the largest elements a[1] and a[n] and fixes the heap, so repeat until the heap becomes empty. The implementations of Exch () and less () are reduced by one to achieve the same implementation as other sorting algorithms (A[0] to a[n-1].
3. Sinking sort
The main work of heap sequencing is done in the second phase. Here we delete the largest element in the heap and put it in the empty position of the array after the heap is shrunk. This process is somewhat similar to the selection sort (all elements are taken in descending order rather than ascending), but the desired comparison is much less because the heap provides an efficient way to find the largest element in the never-sorted part.
proposition: ordering n elements, heap ordering requires less than (2nlgn+2n) comparisons (and half times of exchange).
Proof:The 2N item is derived from the structure of the heap (see above proposition). 2NlgN items from each sinking operation may require a 2lgN comparison (see all propositions above).
4. Summary
Heap sequencing plays an important role in the study of sequencing complexity because it is the only way we know to use space and time optimally simultaneously-and in the worst case it is guaranteed to use ~2NLGN and constant extra space. It is popular when space is tight (for example, in embedded systems or in low-cost mobile devices) because it can achieve (and even machine code) better performance in just a few lines. But many applications of modern systems seldom use it because it cannot take advantage of caching. Array elements are rarely compared to other adjacent elements, so the number of cache misses is much higher than most comparisons are made between adjacent elements, such as quick sort, merge sort, or even hill sort.
On the other hand, the heap-implemented priority queue is becoming increasingly important in modern applications because it guarantees a number of levels of uptime in dynamic scenarios where the insertion operation and the removal of the maximum element operation are mixed.
" Source Download "
Algorithm-Heap Sequencing