Heaps & Priority Queues. (Walls & Mirrors - Remainder of Chapter 11)

Similar documents
Tables, Priority Queues, Heaps

ADT Priority Queue. Heaps. A Heap Implementation of the ADT Priority Queue. Heapsort

The smallest element is the first one removed. (You could also define a largest-first-out priority queue)

CS165: Priority Queues, Heaps

CS302 - Data Structures using C++

Definition of a Heap. Heaps. Priority Queues. Example. Implementation using a heap. Heap ADT

CS200: Tables and Priority Queues

Heaps and Priority Queues

4/3/13. Outline. Part 7. Tables and Priority Queues. Value Oriented Data Structures. Example: Table of Student Points. Table ADT.

Priority queues. Priority queues. Priority queue operations

Outline. Part 7. Tables and Priority Queues. Example: Table of Student Points. Value Oriented Data Structures. Table ADT. Search Keys 4/2/12

Data Structures and Algorithms for Engineers

Tables and Priority Queues

ECE 242 Data Structures and Algorithms. Heaps I. Lecture 22. Prof. Eric Polizzi

Heapsort. Heap data structure

8. Binary Search Tree

Priority Queues. 1 Introduction. 2 Naïve Implementations. CSci 335 Software Design and Analysis III Chapter 6 Priority Queues. Prof.

CS106X Programming Abstractions in C++ Dr. Cynthia Bailey Lee

Binary Trees. Directed, Rooted Tree. Terminology. Trees. Binary Trees. Possible Implementation 4/18/2013

CSC Design and Analysis of Algorithms. Lecture 8. Transform and Conquer II Algorithm Design Technique. Transform and Conquer

! Tree: set of nodes and directed edges. ! Parent: source node of directed edge. ! Child: terminal node of directed edge

CSC Design and Analysis of Algorithms. Lecture 8. Transform and Conquer II Algorithm Design Technique. Transform and Conquer

SCJ2013 Data Structure & Algorithms. Binary Search Tree. Nor Bahiah Hj Ahmad

Priority Queues. e.g. jobs sent to a printer, Operating system job scheduler in a multi-user environment. Simulation environments

How much space does this routine use in the worst case for a given n? public static void use_space(int n) { int b; int [] A;

9. Heap : Priority Queue

HEAPS: IMPLEMENTING EFFICIENT PRIORITY QUEUES

Priority Queues (Heaps)

Tables and Priority Queues

Binary Trees and Binary Search Trees

Tables and Priority Queues!

MID TERM MEGA FILE SOLVED BY VU HELPER Which one of the following statement is NOT correct.

Data Structures and Algorithms

Sorting and Searching

! Tree: set of nodes and directed edges. ! Parent: source node of directed edge. ! Child: terminal node of directed edge

Programming Abstractions

CSCI 104 Binary Trees / Priority Queues / Heaps. Mark Redekopp Michael Crowley

Priority Queues. Lecture15: Heaps. Priority Queue ADT. Sequence based Priority Queue

Topic Binary Trees (Non-Linear Data Structures)

Priority Queues. Chapter 9

Binary Trees, Binary Search Trees

Programming II (CS300)

Computational Optimization ISE 407. Lecture 16. Dr. Ted Ralphs

The ADT priority queue Orders its items by a priority value The first item removed is the one having the highest priority value

Week 10. Sorting. 1 Binary heaps. 2 Heapification. 3 Building a heap 4 HEAP-SORT. 5 Priority queues 6 QUICK-SORT. 7 Analysing QUICK-SORT.

Sorting and Searching

Tree: non-recursive definition. Trees, Binary Search Trees, and Heaps. Tree: recursive definition. Tree: example.

Trees, Binary Trees, and Binary Search Trees

Lec 17 April 8. Topics: binary Trees expression trees. (Chapter 5 of text)

3. Priority Queues. ADT Stack : LIFO. ADT Queue : FIFO. ADT Priority Queue : pick the element with the lowest (or highest) priority.

CS2223: Algorithms Sorting Algorithms, Heap Sort, Linear-time sort, Median and Order Statistics

Trees 1: introduction to Binary Trees & Heaps. trees 1

Heaps. Heaps. A heap is a complete binary tree.

Priority Queues and Heaps. Heaps of fun, for everyone!

Overview of Presentation. Heapsort. Heap Properties. What is Heap? Building a Heap. Two Basic Procedure on Heap

void insert( Type const & ) void push_front( Type const & )

CS 234. Module 8. November 15, CS 234 Module 8 ADT Priority Queue 1 / 22

CSE 241 Class 17. Jeremy Buhler. October 28, Ordered collections supported both, plus total ordering operations (pred and succ)

Algorithms and Data Structures

Priority Queues, Binary Heaps, and Heapsort

Cosc 241 Programming and Problem Solving Lecture 21 (15/5/2017) Heaps

Lecture Notes on Priority Queues

Heaps, Heap Sort, and Priority Queues.

FINALTERM EXAMINATION Fall 2009 CS301- Data Structures Question No: 1 ( Marks: 1 ) - Please choose one The data of the problem is of 2GB and the hard

CS 270 Algorithms. Oliver Kullmann. Binary search. Lists. Background: Pointers. Trees. Implementing rooted trees. Tutorial

Chapter 9. Priority Queue

CS200 Midterm 2 Fall 2007

Heaps Goodrich, Tamassia. Heaps 1

Binary Search Trees Treesort

DATA STRUCTURES AND ALGORITHMS

Heapsort. Why study Heapsort?

Trees. Chapter 6. strings. 3 Both position and Enumerator are similar in concept to C++ iterators, although the details are quite different.

Heaps and Priority Queues

Chapter 20: Binary Trees

COMP : Trees. COMP20012 Trees 219

O(n): printing a list of n items to the screen, looking at each item once.

CSE 373 Data Structures and Algorithms. Lecture 15: Priority Queues (Heaps) III

Heaps. A complete binary tree can be easily stored in an array - place the root in position 1 (for convenience)

A set of nodes (or vertices) with a single starting point

Algorithms and Data Structures

Week 10. Sorting. 1 Binary heaps. 2 Heapification. 3 Building a heap 4 HEAP-SORT. 5 Priority queues 6 QUICK-SORT. 7 Analysing QUICK-SORT.

Properties of a heap (represented by an array A)

Binary heaps (chapters ) Leftist heaps

Heaps. Heaps Priority Queue Revisit HeapSort

Data Structures Lesson 9

Trees. A tree is a directed graph with the property

Tree Data Structures CSC 221

CS302 - Data Structures using C++

COSC Advanced Data Structures and Algorithm Analysis Lab 3: Heapsort

Chapter 10. Sorting and Searching Algorithms. Fall 2017 CISC2200 Yanjun Li 1. Sorting. Given a set (container) of n elements

Data Structures. Trees. By Dr. Mohammad Ali H. Eljinini. M.A. Eljinini, PhD

Data Structures in Java

Computer Science 302 Spring 2007 Practice Final Examination: Part I

Heaps. 2/13/2006 Heaps 1

Design and Analysis of Algorithms - Chapter 6 6

- 1 - Handout #22S May 24, 2013 Practice Second Midterm Exam Solutions. CS106B Spring 2013

Binary Search Trees. BinaryTree<E> Class (cont.) Section /27/2017

binary tree empty root subtrees Node Children Edge Parent Ancestor Descendant Path Depth Height Level Leaf Node Internal Node Subtree

Sorting. Bubble sort method. Bubble sort properties. Quick sort method. Notes. Eugeniy E. Mikhailov. Lecture 27. Notes. Notes

Data Structure - Binary Tree 1 -

Transcription:

Heaps & Priority Queues (Walls & Mirrors - Remainder of Chapter 11) 1

Overview Array-Based Representation of a Complete Binary Tree Heaps The ADT Priority Queue Heap Implementation of the ADT Priority Queue Heapsort 2

Complete Binary Tree Recall that a binary tree of height h is said to be complete if it is full down to level h 1, and level h is filled from left to right. Examples: Now, recall our array-based representation of a binary tree: 3

Array-Based Representation of a Binary Tree i Item Left Child Right Child 0 Pam 1 2 1 Joe 3 4 2 Sue 5 6 3 Bob 7 8 4 Mike 9-1 5 Sam -1-1 6 Tom -1-1 7 Ann -1-1 8 Jane -1-1 9 Mary -1-1 root 0 Pam free 10 Joe Sue Bob Mike Sam Tom Ann Jane Mary 4

Left Child & Right Child in a Complete, Array-Based Binary Tree Suppose that the nodes of a binary tree are stored in an array as follows: First, store the root, which is at level 1. Next, store the nodes at level 2; Then, store the nodes at level 3;... Suppose also that at every level, the nodes are stored from left to right. If the binary tree is complete, then for any node at array position i, its left child will be at position 2*i + 1, and its right child will be at position 2*i + 2. 5

Left Child & Right Child in a Complete, Array-Based Binary Tree i Item Left Child 2*i + 1 Right Child 0 Pam 1 1 2 1 Joe 3 3 4 2 Sue 5 5 6 3 Bob 7 7 8 4 Mike 9 9-1 5 Sam -1 11-1 6 Tom -1 13-1 7 Ann -1 15-1 8 Jane -1 17-1 9 Mary -1 19-1 Pam Joe Sue Bob Mike Sam Tom Ann Jane Mary LeftChild(i) = 2*i + 1 RightChild(i) = 2*i + 2 6

Parent in a Complete, Array-Based Binary Tree If the array-based binary tree is complete, then for any node at array position i, its parent will be at position Examples: (i 1) / 2 i = 4: (i 1) / 2 = 3 / 2 = 1 i = 3: (i 1) / 2 = 2 / 2 = 1 i = 2: (i 1) / 2 = 1 / 2 = 0 i = 1: (i 1) / 2 = 0 / 2 = 0 i = 0: (i 1) / 2 = -1/ 2 = -1 7

Parent in a Complete, Array-Based Binary Tree i Item Parent (i 1) / 2 0 Pam -1-1 1 Joe 0 0 2 Sue 0 0 3 Bob 1 1 4 Mike 1 1 5 Sam 2 2 6 Tom 2 2 7 Ann 3 3 8 Jane 3 3 9 Mary 4 4 Pam Joe Sue Bob Mike Sam Tom Ann Jane Mary Parent(i) = (i 1) / 2 8

Array-Based Representation of a Complete Binary Tree Conclusion: For an array-based representation of a complete binary tree, there is an easy way to determine the parent and children of any node without following left and right child indices (or pointers). Consequently, in this case, it is sufficient to store the data items only, and indices (or pointers) to parents and children are not necessary. 9

Array-Based Representation of a Complete Binary Tree Pam Joe Sue Bob Mike Sam Tom Ann Jane Mary Pam Joe Sue Bob Mike Sam Tom Ann Jane Mary 10

Heaps A heap is a complete binary tree that is either: empty, or consists of a root and two subtrees, such that both subtrees are heaps, and the root contains a search key that is the search key of each of its children. 11

Array-Based Representation of a Heap Search Item Key 10 Tom 7 Pam 9 Sue 5 Mary 6 Mike 8 Sam 1 Ann 4 Joe 2 Bob 3 Jane 4 5 7 Pam Tom Sue Mary Mike Sam Ann 2 Joe Bob Jane 3 6 10 8 9 1 12

Array-Based Representation of a Heap Note that, for any node, the search key of its left child is not necessarily or the search key of its right child. The only constraint is that any parent node must have a search key that is the search key of both of its children. Note that this is sufficient to ensure that the item with the greatest search key in the heap is stored at the root. In the array-based representation we have discussed, the item with the greatest search key will always be at position 0 of the array. 13

The ADT Priority Queue A priority queue is an ADT in which items are ordered by a priority value. The item with the highest priority is always the next to be removed from the queue. (Highest Priority In, First Out: HPIFO) Supported operations include: Create an empty priority queue Destroy a priority queue Determine whether a priority queue is empty Insert a new item into a priority queue Retrieve, and then delete from the priority queue the item with the highest priority value We shall implement a priority queue using a heap. 14

PriorityQ: Array-Based Implementation const int MaxItems = 100; typedef int KeyType; // max # items in PriorityQ // PriorityQ search-keys are int s struct dataitem // all data for an item is put into { KeyType key; // one struct for convenience // other data members are included here }; typedef dataitem PQItemType; // items in PriorityQ are dataitems // returns pqitem s search-key KeyType getkey( const PQItemType &pqitem ) { return( pqitem.key ); } 15

PriorityQ: Array-Based Implementation typedef PQItemType HeapItemType; class PriorityQ { }; public: // declarations of public member functions private: HeapItemType items[maxitems]; int size; 16

PriorityQ: Public Member Function Definitions // default constructor, which creates a new empty PriorityQ PriorityQ::PriorityQ( ) : size( 0 ) { } // copy constructor and destructor are supplied by the compiler // returns true if the PriorityQ is empty, otherwise returns false bool PriorityQ::pqIsEmpty( ) const { return size = = 0; } 17

PriorityQ: Retrieve & Delete Consider the operation, Retrieve, and then delete from the priority queue the item with the highest priority value. In a heap where search keys represent the priority of the items, the item with the highest priority is stored at the root. Consequently, retrieving the item with the highest priority value is trivial. However, if the root of a heap is deleted we will be left with two separate heaps. We need a way to transform the remaining nodes back into a single heap. 18

PriorityQ: Public Member Function Definition // retrieve, and then delete from the PriorityQ the item // with the highest priority value bool PriorityQ::pqRetrieve( PQItemType &priorityitem ) { if( pqisempty( ) ) return false; } // set priorityitem to the highest priority item in the PriorityQ, // which is stored in the root of a heap priorityitem = items[ 0 ]; // move item from the last node in the heap to the root, // and delete the last node items[ 0 ] = items[ size ]; // transform the resulting semiheap back into a heap heaprebuild( 0 ); return true; 19

Semiheap A semiheap is a complete binary tree in which the root s left and right subtrees are both heaps. 10 25 45 55 45 55 60 15 50 35 20 5 10 40 30 25 20

Rebuilding a Heap: Basic Idea Problem: Transform a semiheap with given root into a heap. Let key( n ) represent the search key value of node n. 1) If the root of the semiheap is not a leaf, and key( root ) < key( child of root with larger search key value ) then swap the item in the root with the child containing the larger search key value. 2) If any items were swapped in step 1, then repeat step 1 with the subtree rooted at the node whose item was swapped with the root. If no items were swapped, then we are done: the resulting tree is a heap. 21

Retrieve & Delete: Example move 25 to here 60 55 45 15 50 35 20 5 10 40 30 25 Retrieve the item with the highest priority value (= 60) from the root. Move the item from the last node in the heap (= 25) to the root, and delete the last node. 22

Rebuilding a Heap: Example (Cont d.) swap 25 with the item in this node 15 50 35 20 5 10 40 30 25 55 45 The resulting data structure is a semiheap, a complete binary tree in which the root s left and right subtrees are both heaps. To transform this semiheap into a heap, start by swapping the item in the root with its child containing the larger search key value. 23

Rebuilding a Heap: Example (Cont d.) 55 25 45 15 50 35 20 Note that the subtree rooted at the node containing 25 is a semiheap. As before, swap the item in the root of this semiheap with its child containing the larger search key value. 5 10 40 30 swap 25 with the item in this node 24

Rebuilding a Heap: Example (Cont d.) 55 50 45 15 25 35 20 Note that the subtree rooted at the node containing 25 is a semiheap. As before, swap the item in the root of this semiheap with its child containing the larger search key value. 5 10 40 30 swap 25 with the item in this node 25

Rebuilding a Heap: Example (Cont d.) 55 50 45 15 40 35 20 5 10 25 30 Note that the subtree rooted at the node containing 25 is a semiheap with two empty subtrees. Since the root of this semiheap is also a leaf, we are done. The resulting tree rooted at the node containing 55 is a heap. 26

PriorityQ: Private Member Function Definition // transform a semiheap with the given root into a heap void PriorityQ::heapRebuild( int root ) { int child = 2 * root + 1; // set child to root s left child, if any if( child < size ) // if root s left child exists... } { int rightchild = child + 1; } if( rightchild < size && getkey( items[ rightchild ] ) > getkey( items[ child ] ) ) child = rightchild; // child has the larger search key if( getkey( items[ root ] ) < getkey( items[ child ] ) ) { swap( items[ root ], items[ child ] ); } heaprebuild( child ); 27

PriorityQ Insert: Basic Idea Problem: Insert a new item into a priority queue, where the priority queue is implemented as a heap. Let key( n ) represent the search key value of node n. 1) Store the new item in a new node at the end of the heap. 2) If the node containing the new item has a parent, and key( node containing new item ) > key( node s parent ) then swap the new item with the item in its parent node. 3) If the new item was swapped with its parent in step 2, then repeat step 2 with the new item in the parent node. If no items were swapped, then we are done: the resulting tree is a heap containing the new item. 28

PriorityQ Insert: Example 55 50 45 15 40 35 20 Suppose that we wish to insert an item with search key = 47. First, we store the new item in a new node at the end of the heap. 5 10 25 30 47 29

PriorityQ Insert: Example (Cont d.) 55 50 45 Since the search key of the new item (= 47) > the search key of its parent (= 35), swap the new item with its parent. 15 40 35 20 5 10 25 30 47 30

PriorityQ Insert: Example (Cont d.) 55 50 45 Since the search key of the new item (= 47) > the search key of its parent (= 45), swap the new item with its parent. 15 40 47 20 5 10 25 30 35 31

PriorityQ Insert: Example (Cont d.) 55 50 47 15 40 45 20 Since the search key of the new item (= 47) the search key of its parent (= 55), we are done. The resulting tree is a heap containing the new item. 5 10 25 30 35 32

PriorityQ: Public Member Function Definition // insert newitem into a PriorityQ bool PriorityQ::pqInsert( const PQItemType &newitem ) { if( size > MaxItems ) return false; } items[ size ] = newitem; // store newitem at the end of a heap int newpos = size, parent = (newpos 1) / 2; while( parent >= 0 && getkey( items[ newpos ] ) > getkey( items[ parent ] ) ) { swap( items[ newpos ], items[ parent ] ); } newpos = parent; parent = (newpos 1) / 2; size++; return true; 33

Heap-Based PriorityQ: Efficiency In the best case, no swaps are needed after an item is inserted at the end of the heap. In this case, insertion requires constant time, which is O( 1 ). In the worst case, an item inserted at the end of a heap will be swapped until it reaches the root, requiring O( height of tree ) swaps. Since heaps are complete binary trees, and hence, balanced, the height of a heap with n nodes is log 2 (n + 1). Therefore, in this case, insertion is O( log n ). In the average case, the inserted item will travel halfway to the root, which makes insertion in this case also O( log n ). The retrieve & delete operation spends most of its time rebuilding a heap. A similar analysis shows that this is O( log n ) in the best, average, and worst cases. The average and worst case performance of these operations is the same as for a balanced, binary tree. 34

Heapsort: Basic Idea Problem: Arrange an array of items into sorted order. 1) Transform the array of items into a heap. 2) Invoke the retrieve & delete operation repeatedly, to extract the largest item remaining in the heap, until the heap is empty. Store each item retrieved from the heap into the array from back to front. Note: We will refer to the version of heaprebuild used by Heapsort as rebuildheap, to distinguish it from the version implemented for the class PriorityQ. 35

Transform an Array Into a Heap: Basic Idea We have seen how the consecutive items in an array can be considered as the nodes of a complete binary tree. Note that every leaf is a heap, since a leaf has two empty subtrees. (Note that the last node in the array is a leaf.) It follows that if each child of a node is either a leaf or empty, then that node is the root of a semiheap. We can transform an array of items into a heap by repetitively invoking rebuildheap, first on the parent of the last node in the array (which is the root of a semiheap), followed by each preceding node in the array (each of which becomes the root of a semiheap). 36

Transform an Array Into a Heap: Example 6 3 5 7 0 1 2 3 rebuildheap 6 3 5 7 2 4 10 9 2 4 4 5 10 6 The items in the array, above, can be considered to be stored in the complete binary tree shown at right. Note that leaves 2, 4, 9 & 10 are heaps; nodes 5 & 7 are roots of semiheaps. rebuildheap is invoked on the parent of the last node in the array (= 9). 9 7 37

Transform an Array Into a Heap: Example 6 3 5 9 0 1 2 3 rebuildheap 6 3 5 9 2 4 10 2 4 4 5 10 6 Note that nodes 2, 4, 7, 9 & 10 are roots of heaps; nodes 3 & 5 are roots of semiheaps. rebuildheap is invoked on the node in the array preceding node 9. 7 7 7 38

Transform an Array Into a Heap: Example 6 3 10 9 0 1 2 3 rebuildheap 6 3 10 9 2 4 5 2 4 4 5 5 6 Note that nodes 2, 4, 5, 7, 9 & 10 are roots of heaps; node 3 is the root of a semiheap. rebuildheap is invoked on the node in the array preceding node 10. 7 7 7 39

Transform an Array Into a Heap: Example 6 9 10 3 0 1 2 3 rebuildheap 6 9 10 3 2 4 5 2 4 4 5 5 6 7 7 Note that nodes 2, 4, 5, 7 & 10 are roots of heaps; node 3 is the root of a semiheap. rebuildheap is invoked recursively on node 3 to complete the transformation of the semiheap rooted at 9 into a heap. 7 40

Transform an Array Into a Heap: Example 6 9 10 7 0 1 2 3 rebuildheap 6 9 10 7 2 4 5 3 2 4 4 5 5 6 3 7 Note that nodes 2, 3, 4, 5, 7, 9 & 10 are roots of heaps; node 6 is the root of a semiheap. The recursive call to rebuildheap returns to node 9. rebuildheap is invoked on the node in the array preceding node 9. 41

Transform an Array Into a Heap: Example 10 9 6 7 2 4 5 3 0 1 2 3 4 5 6 7 10 9 6 Note that node 10 is now the root of a heap. The transformation of the array into a heap is complete. 7 2 4 5 3 42

Transform an Array Into a Heap (Cont d.) Transforming an array into a heap begins by invoking rebuildheap on the parent of the last node in the array. Recall that in an array-based representation of a complete binary tree, the parent of any node at array position, i, is (i 1) / 2 Since the last node in the array is at position n 1, it follows that transforming an array into a heap begins with the node at position (n 2) / 2 = n / 2 1 and continues with each preceding node in the array. 43

Transform an Array Into a Heap: C++ // transform array a[ ], containing n items, into a heap for( int root = n/2 1; root >= 0; root ) { } // transform a semiheap with the given root into a heap rebuildheap( a, root, n ); 44

Rebuild a Heap: C++ // transform a semiheap with the given root into a heap void rebuildheap( ItemType a[ ], int root, int n ) { int child = 2 * root + 1; // set child to root s left child, if any if( child < n ) // if root s left child exists... } { int rightchild = child + 1; } if( rightchild < n && a[ rightchild ] > a[ child ] ) child = rightchild; // child indicates the larger item if( a[ root ] < a[ child ] ) { swap( a[ root ], a[ child ] ); rebuildheap( a, child, n ); } 45

Transform a Heap Into a Sorted Array After transforming the array of items into a heap, the next step in Heapsort is to: invoke the retrieve & delete operation repeatedly, to extract the largest item remaining in the heap, until the heap is empty. Store each item retrieved from the heap into the array from back to front. If we want to perform the preceding step without using additional memory, we need to be careful about how we delete an item from the heap and how we store it back into the array. 46

Transform a Heap Into a Sorted Array: Basic Idea Problem: Transform array a[ ] from a heap of n items into a sequence of n items in sorted order. Let last represent the position of the last node in the heap. Initially, the heap is in a[ 0.. last ], where last = n 1. 1) Move the largest item in the heap to the beginning of an (initially empty) sorted region of a[ ] by swapping a[0] with a[ last ]. 2) Decrement last. a[0] now represents the root of a semiheap in a[ 0.. last ], and the sorted region is in a[ last + 1.. n 1 ]. 3) Invoke rebuildheap on the semiheap rooted at a[0] to transform the semiheap into a heap. 4) Repeat steps 1-3 until last = -1. When done, the items in array a[ ] will be arranged in sorted order. 47

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 10 9 6 7 2 4 5 3 Heap 3 10 9 6 7 2 4 5 We start with the heap that we formed from an unsorted array. The heap is in a[0..7] and the sorted region is empty. We move the largest item in the heap to the beginning of the sorted region by swapping a[0] with a[7]. 48

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 3 9 6 7 2 4 5 10 Semiheap Sorted rebuildheap 3 9 6 a[0..6] now represents a semiheap. a[7] is the sorted region. Invoke rebuildheap on the semiheap rooted at a[0]. 7 2 4 5 49

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 9 3 6 7 2 4 5 10 Becoming a Heap Sorted rebuildheap 9 3 6 rebuildheap is invoked recursively on a[1] to complete the transformation of the semiheap rooted at a[0] into a heap. 7 2 4 5 50

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 9 7 6 3 2 4 5 10 Heap Sorted 9 7 6 3 2 4 5 a[0] is now the root of a heap in a[0..6]. We move the largest item in the heap to the beginning of the sorted region by swapping a[0] with a[6]. 51

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 5 7 6 3 2 4 9 10 Semiheap Sorted rebuildheap 5 7 6 a[0..5] now represents a semiheap. a[6..7] is the sorted region. Invoke rebuildheap on the semiheap rooted at a[0]. 3 2 4 52

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 7 5 6 3 2 4 9 10 Heap Sorted rebuildheap 7 5 6 3 2 4 Since a[1] is the root of a heap, a recursive call to rebuildheap does nothing. a[0] is now the root of a heap in a[0..5]. We move the largest item in the heap to the beginning of the sorted region by swapping a[0] with a[5]. 53

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 4 5 6 3 2 7 9 10 Semiheap Sorted rebuildheap 4 5 6 a[0..4] now represents a semiheap. a[5..7] is the sorted region. Invoke rebuildheap on the semiheap rooted at a[0]. 3 2 54

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 6 5 4 3 2 7 9 10 Heap Sorted 5 4 3 2 6 a[0] is now the root of a heap in a[0..4]. We move the largest item in the heap to the beginning of the sorted region by swapping a[0] with a[4]. 55

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 2 5 4 3 6 7 9 10 Semiheap Sorted rebuildheap 2 5 4 a[0..3] now represents a semiheap. a[4..7] is the sorted region. Invoke rebuildheap on the semiheap rooted at a[0]. 3 56

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 5 2 4 3 6 7 9 10 Becoming a Heap Sorted rebuildheap 5 2 4 rebuildheap is invoked recursively on a[1] to complete the transformation of the semiheap rooted at a[0] into a heap. 3 57

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 5 3 4 2 6 7 9 10 Heap Sorted 2 5 3 4 a[0] is now the root of a heap in a[0..3]. We move the largest item in the heap to the beginning of the sorted region by swapping a[0] with a[3]. 58

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 2 3 4 5 6 7 9 10 Semiheap Sorted rebuildheap 2 3 4 a[0..2] now represents a semiheap. a[3..7] is the sorted region. Invoke rebuildheap on the semiheap rooted at a[0]. 59

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 4 3 2 5 6 7 9 10 Heap Sorted 4 3 2 a[0] is now the root of a heap in a[0..2]. We move the largest item in the heap to the beginning of the sorted region by swapping a[0] with a[2]. 60

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 2 3 4 5 6 7 9 10 Semiheap Sorted rebuildheap 3 2 a[0..1] now represents a semiheap. a[2..7] is the sorted region. Invoke rebuildheap on the semiheap rooted at a[0]. 61

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 3 2 4 5 6 7 9 10 Heap Sorted 2 3 a[0] is now the root of a heap in a[0..1]. We move the largest item in the heap to the beginning of the sorted region by swapping a[0] with a[1]. 62

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 2 3 4 5 6 7 9 10 Heap Sorted 2 a[1..7] is the sorted region. Since a[0] is a heap, a recursive call to rebuildheap does nothing. We move the only item in the heap to the beginning of the sorted region. 63

Transform a Heap Into a Sorted Array: Example 0 1 2 3 4 5 6 7 a[ ]: 2 3 4 5 6 7 9 10 Sorted Since the sorted region contains all the items in the array, we are done. 64

Heapsort: C++ void heapsort( ItemType a[ ], int n ) { // transform array a[ ] into a heap for( int root = n/2 1; root >= 0; root ) rebuildheap( a, root, n ); for( int last = n 1; last > 0; ) { // move the largest item in the heap, a[ 0.. last ], to the // beginning of the sorted region, a[ last+1.. n 1 ], and // increase the sorted region swap( a[0], a[ last ] ); last ; } } // transform the semiheap in a[ 0.. last ] into a heap rebuildheap( a, 0, last ); 65

Heapsort: Efficiency rebuildheap( ) is invoked n / 2 times to transform an array of n items into a heap. rebuildheap( ) is then called n 1 more times to transform the heap into a sorted array. From our analysis of the heap-based, Priority Queue, we saw that rebuilding a heap takes O( log n ) time in the best, average, and worst cases. Therefore, Heapsort requires O( [ n / 2 + (n 1) ] * log n ) = O( n log n ) time in the best, average and worst cases. This is the same growth rate, in all cases, as Mergesort, and the same best and average cases as Quicksort. Knuth s analysis shows that, in the average case, Heapsort requires about twice as much time as Quicksort, and 1.5 times as much time as Mergesort (without requiring additional storage). 66

Growth Rates for Selected Sorting Algorithms Best case Average case ( ) Worst case Selection sort n 2 n 2 n 2 Bubble sort n n 2 n 2 Insertion sort n n 2 n 2 Mergesort n * log 2 n n * log 2 n n * log 2 n Heapsort n * log 2 n n * log 2 n n * log 2 n Treesort n * log 2 n n * log 2 n n 2 Quicksort n * log 2 n n * log 2 n n 2 Radix sort n n n According to Knuth, the average growth rate of Insertion sort is about 0.9 times that of Selection sort and about 0.4 times that of Bubble Sort. Also, the average growth rate of Quicksort is about 0.74 times that of Mergesort and about 0.5 times that of Heapsort. 67