150 likes | 164 Views
GRIFFITH COLLEGE DUBLIN. Programming & Data Structures. Heap Sort and Priority Queue. The Heapsort Algorithm. The heapsort algorithm uses the fact that the largest element stored at the root A[1].
E N D
GRIFFITH COLLEGE DUBLIN Programming & Data Structures Heap Sort and Priority Queue Lecture 12
The Heapsort Algorithm • The heapsort algorithm uses the fact that the largest element stored at the root A[1]. • We can place this value in its correct position by swapping it with the value at the final position A[n]. • If we decrement the size of the heap and Heapify from A[1] we can restore the heap • The heapsort algorithm then repeats this process for the heap of size n – 1 down to heap of size 2. Lecture 12
Heapsort Algorithm Heapsort(A) Build-Heap(A) for i = length[A] downto 2 exchange A[1] and A[i] heap-size[A] = heap-size[A] – 1 Heapify(A, 1) endfor endalg Lecture 12
16 14 14 10 8 10 7 9 3 7 9 3 8 4 1 16 2 4 2 1 10 9 8 9 8 3 7 1 3 4 7 1 2 4 16 2 14 16 10 14 8 7 7 3 4 3 2 1 9 2 8 9 4 1 16 16 10 14 10 14 Example HeapSort Lecture 12
4 3 2 3 2 1 7 8 9 7 8 9 1 4 16 16 10 14 10 14 1 2 2 3 1 3 7 8 9 4 7 8 9 4 16 10 14 16 10 14 Example HeapSort cont. Lecture 12
Analysis of HeapSort • The Heapsort procedure takes time O(n lg n), since the call to Build-Heap takes time O(n) and each of the n-1 calls to Heapify takes time O(lg n) • Heapsort is an excellent algorithm, but a good implementation of quicksort usually beats it in practice. • Nevertheless, the heap data structure itself has enormous utility. • One such use is as an efficient priority queue. Lecture 12
Priority Queue • Many applications require that we process records with keys in order, but not necessarily in full sorted order • Items in a priority queue are not processed strictly in order of entry into the queue • Items can be placed on the queue at any time, but processing always takes the item with the largest key • The priority queue is a generalised queue Abstract Data Structure (ADT) • In fact, the priority queue is a proper generalisation of the stact and the queue ADTs, as we can implement either with priority queues, using appropriate priorities Lecture 12
Definition • A priority queue is a data structure of items with keys that support two basic operations : insert a new item, and delete the item with the largest key. • Applications of priority queues include: • Simulation Systems, where events need to be processed chronologically. • Job scheduling in computer systems. • The Heap Data Structure is an efficient structure for implementing a simple priority queue • In practice, priority queues are more complex than the simple definition above. Lecture 12
Priority Queue • One of the reasons that priority queue implementations are so useful is their flexibility • For that reason any implementation will need to support some of the following operations • Construct a priority queue from N given items • Insert a new item • Delete the maximum item • Change the priority of an arbitrary specified item • Delete an arbitrary specified item • We take “maximum” to mean “any record with the largest key value”. Lecture 12
Heap Extract • As with many data structures, we also need to add standard initialise, test if empty and perhaps destroy and copy operations • Lets look at insert and delete maximum. Heap-Extract-Max(A) if heap-size[A] < 1 then error “heap underflow” endif max = A[1] A[1] = A[heap-size[A]] heap-size[A] = heap-size[A] – 1 Heapify(A, 1) return max endalg • The running time of Heap-Extract-Max is O(lg n), since it performs only a constant amount of work on top of the O(lg n) time for Heapify Lecture 12
Heap Insert • Heap-Insert inserts a node into heap A. Expand by adding a new leaf to the tree. Traverse a path from this leaf toward the root to find a place for the new element. Heap-Insert(A, key) heap-size[A] = heap-size[A] + 1 i = heap-size[A] while i > 1 and A[Parent(i)] < key do A[i] = A[Parent(i)] i = Parent(i) endwhile A[i] = key endalg • Running time of on an n-element heap is O(lg n) since the path traced from the new leaf to the root has length O(lg n) • This is an example of a non-recursive sift up procedure. Lecture 12
16 16 14 10 14 10 7 9 3 7 9 3 8 8 1 1 2 4 2 4 16 16 10 15 10 14 9 3 14 9 3 8 8 1 7 1 7 2 4 2 4 Example Heap Insert (15) (a) (b) (d) (c) (a) is the heap before insert, (b) add a leaf (c) Copy from leaf to root until place fornew item found(d) Add new item Lecture 12
Heap Delete • To construct a priority queue it is simply necessary to call Build-Heap for the array • To delete an arbitrarily specified item from the queue follow the design for Heap-Extract-Max Heap-Delete(A, i) if heap-size[A] < 1 then error “heap underflow” endif item = A[i] A[i] = A[heap-size[A]] heap-size[A] = heap-size[A] – 1 Heapify(A, i) return item endalg • Which will run in at worst O(lg n) time Lecture 12
Changing Priorities • What if we want to change a node priority? • Implement based on the existing functions? • ‘Delete old value’ and ‘Insert new value’ • Each of these will run in O(lg n) time, which means that the procedure will also run in O(lg n) time. • The heap provides an efficient implementation for a priority queue using the operations outlined, but is not so efficient in other cases • For example, an operation which may sometimes be required is the join operation to merge two priority queues • There are other implementations (e.g. doubly linked list) which support this operation more efficiently Lecture 12
Summary • The heapsort algorithm uses the fact that the largest element stored at the root A[1]. • We can place this value in its correct position by swapping it with the value at the final position A[n]. • If we decrement the size of the heap and Heapify from A[1] we can restore the heap • A heap can be an efficient implementation for a priority queue • To implement this we need to develop insert, delete and extract max algorithms Lecture 12