SlideShare a Scribd company logo
Heaps & Priority Queues
Overview Array-Based Representation of a Complete Binary Tree Heaps The ADT Priority Queue Heap Implementation of the ADT Priority Queue Heapsort
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:
Array-Based  Representation of a Binary Tree Bob Mike Sam Tom Pam Joe Sue Ann Jane Mary root 0 free 10
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.
Left Child  &  Right Child  in a  Complete,  Array-Based Binary Tree LeftChild(i)  =  2*i + 1 RightChild(i)  =  2*i + 2 Bob Mike Sam Tom Pam Joe Sue Ann Jane Mary
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    (i – 1) / 2   Examples: 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
Parent  in a  Complete , Array-Based Binary Tree Parent(i)  =    (i – 1) / 2   Bob Mike Sam Tom Pam Joe Sue Ann Jane Mary
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.
Array-Based Representation of a Complete  Binary Tree Bob Mike Sam Tom Pam Joe Sue Ann Jane Mary
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.
Array-Based Representation of a Heap Mary Mike Sam Ann Tom Pam Sue Joe Bob Jane 3 2 1 5 4 7 6 9 8 10
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.
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.
PriorityQ:  Array-Based Implementation const  int  MaxItems = 100; // max # items in PriorityQ typedef  int  KeyType; // 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 ); }
PriorityQ:  Array-Based Implementation typedef  PQItemType  HeapItemType; class  PriorityQ { public: // declarations of public member functions private: HeapItemType  items[MaxItems]; int  size; };
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; }
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.
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; }
Semiheap A  semiheap  is a  complete  binary tree in which the root’s left and right subtrees are both  heaps . 10 5 10 40 30 15 50 35 20 55 60 45 25 55 45 25
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.
Retrieve & Delete:  Example 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. 5 10 40 30 15 50 35 20 55 45 60 25 move 25 to here
Rebuilding a Heap:  Example (Cont’d.) 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. 15 50 35 20 5 10 40 30 55 45 25 swap 25 with the item in this node
Rebuilding a Heap:  Example (Cont’d.) 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. 15 50 35 20 5 10 40 30 25 45 55 swap 25 with the item in this node
Rebuilding a Heap:  Example (Cont’d.) 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. 15 25 35 20 5 10 40 30 50 45 55 swap 25 with the item in this node
Rebuilding a Heap:  Example (Cont’d.) 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 . 15 40 35 20 5 10 25 30 50 45 55
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 ); } } }
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.
PriorityQ Insert:  Example 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. 15 40 35 20 5 10 25 30 50 45 55 47
PriorityQ Insert:  Example (Cont’d.) 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 50 45 55 47
PriorityQ Insert:  Example (Cont’d.) 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 50 45 55 35
PriorityQ Insert:  Example (Cont’d.) 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. 15 40 45 20 5 10 25 30 50 47 55 35
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; }
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 .
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 .
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).
Transform an Array Into a Heap:  Example 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). 7 2 4 10 9 3 5 6 5 4 3 2 1 0 4 2 7 5 3 6 7 6 9 10 rebuildHeap
Transform an Array Into a Heap:  Example 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. rebuildHeap 9 2 4 10 7 3 5 6 5 4 3 2 1 0 4 2 9 5 3 6 7 6 7 10
Transform an Array Into a Heap:  Example 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. rebuildHeap 9 2 4 5 7 3 10 6 5 4 3 2 1 0 4 2 9 10 3 6 7 6 7 5
Transform an Array Into a Heap:  Example 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 . rebuildHeap 3 2 4 5 7 9 10 6 5 4 3 2 1 0 4 2 3 10 9 6 7 6 7 5
Transform an Array Into a Heap:  Example 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. rebuildHeap 7 2 4 5 3 9 10 6 5 4 3 2 1 0 4 2 7 10 9 6 7 6 3 5
Transform an Array Into a Heap:  Example 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 9 6 10 5 4 3 2 1 0 4 2 7 6 9 10 7 6 3 5
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.
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 ); }
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 ); } } }
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.
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.
Transform a Heap Into a Sorted Array:  Example 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]. 7 2 4 5 3 9 6 10 4 2 7 6 9 10 5 4 3 2 1 0 7 6 3 5 a[ ]: Heap
Transform a Heap Into a Sorted Array:  Example 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 9 6 3 4 2 7 6 9 3 5 4 3 2 1 0 7 6 10 5 a[ ]: Semiheap Sorted rebuildHeap
Transform a Heap Into a Sorted Array:  Example 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 3 6 9 4 2 7 6 3 9 5 4 3 2 1 0 7 6 10 5 a[ ]: Becoming a Heap Sorted rebuildHeap
Transform a Heap Into a Sorted Array:  Example 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]. 3 2 4 5 7 6 9 4 2 3 6 7 9 5 4 3 2 1 0 7 6 10 5 a[ ]: Heap Sorted
Transform a Heap Into a Sorted Array:  Example 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 7 6 5 4 2 3 6 7 5 5 4 3 2 1 0 7 6 10 9 a[ ]: Semiheap Sorted rebuildHeap
Transform a Heap Into a Sorted Array:  Example 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]. 3 2 4 5 6 7 4 2 3 6 5 7 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted rebuildHeap
Transform a Heap Into a Sorted Array:  Example 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 5 6 4 7 2 3 6 5 4 5 4 3 2 1 0 7 6 10 9 a[ ]: Semiheap Sorted rebuildHeap
Transform a Heap Into a Sorted Array:  Example 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]. 3 2 5 4 6 7 2 3 4 5 6 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted
Transform a Heap Into a Sorted Array:  Example a[0..3] now represents a semiheap. a[4..7] is the sorted region. Invoke  rebuildHeap  on the semiheap rooted at a[0]. 3 5 4 2 7 6 3 4 5 2 5 4 3 2 1 0 7 6 10 9 a[ ]: Semiheap Sorted rebuildHeap
Transform a Heap Into a Sorted Array:  Example rebuildHeap  is invoked recursively on a[1] to complete the transformation of the semiheap rooted at a[0] into a heap. Becoming a Heap 3 2 4 5 7 6 3 4 2 5 5 4 3 2 1 0 7 6 10 9 a[ ]: Sorted rebuildHeap
Transform a Heap Into a Sorted Array:  Example 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]. 2 3 4 5 7 6 2 4 3 5 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted
Transform a Heap Into a Sorted Array:  Example a[0..2] now represents a semiheap. a[3..7] is the sorted region. Invoke  rebuildHeap  on the semiheap rooted at a[0]. 3 4 2 7 6 5 4 3 2 5 4 3 2 1 0 7 6 10 9 a[ ]: Semiheap Sorted rebuildHeap
Transform a Heap Into a Sorted Array:  Example 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]. 3 2 4 7 6 5 2 3 4 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted
Transform a Heap Into a Sorted Array:  Example a[0..1] now represents a semiheap. a[2..7] is the sorted region. Invoke  rebuildHeap  on the semiheap rooted at a[0]. 3 2 7 6 5 4 3 2 5 4 3 2 1 0 7 6 10 9 a[ ]: Semiheap Sorted rebuildHeap
Transform a Heap Into a Sorted Array:  Example 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]. 2 3 7 6 5 4 2 3 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted
Transform a Heap Into a Sorted Array:  Example 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. 2 7 6 5 4 3 2 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted
Transform a Heap Into a Sorted Array:  Example Since the sorted region contains all the items in the array, we are done. 7 6 5 4 3 2 5 4 3 2 1 0 7 6 10 9 a[ ]: Sorted
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 ); } }
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).
Growth Rates for Selected Sorting Algorithms †   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.

More Related Content

PPTX
AVL Tree Data Structure
PPT
Red black tree
PPTX
Trees (data structure)
PPTX
Doubly Linked List
PPTX
Binary Heap Tree, Data Structure
PPTX
Priority Queue in Data Structure
PPTX
Data structure - Graph
PPT
Binary search tree(bst)
AVL Tree Data Structure
Red black tree
Trees (data structure)
Doubly Linked List
Binary Heap Tree, Data Structure
Priority Queue in Data Structure
Data structure - Graph
Binary search tree(bst)

What's hot (20)

PPTX
B and B+ tree
PPTX
PPSX
Data Structure (Tree)
PPT
PPTX
PRIM'S ALGORITHM
PDF
Ai lecture 7(unit02)
PPTX
Breadth First Search & Depth First Search
PPTX
Analysis of algorithm
PDF
AD3251-Data Structures Design-Notes-Searching-Hashing.pdf
PPTX
Binary Tree in Data Structure
PDF
Data Structure: Algorithm and analysis
PPTX
Hashing in datastructure
PPT
Insertion sort bubble sort selection sort
PPT
B trees in Data Structure
PPTX
Stack operation algorithms with example
PPT
Binary search tree in data structures
PPTX
Insertion sort
PPTX
Ppt of operations on one way link list
PDF
Binary Search - Design & Analysis of Algorithms
PPTX
Insertion sort
B and B+ tree
Data Structure (Tree)
PRIM'S ALGORITHM
Ai lecture 7(unit02)
Breadth First Search & Depth First Search
Analysis of algorithm
AD3251-Data Structures Design-Notes-Searching-Hashing.pdf
Binary Tree in Data Structure
Data Structure: Algorithm and analysis
Hashing in datastructure
Insertion sort bubble sort selection sort
B trees in Data Structure
Stack operation algorithms with example
Binary search tree in data structures
Insertion sort
Ppt of operations on one way link list
Binary Search - Design & Analysis of Algorithms
Insertion sort
Ad

Viewers also liked (20)

PPT
Priority queues
PPT
Algorithm: priority queue
PPTX
Priority queue
PDF
computer notes - Priority queue
PDF
Heaps
PDF
Priority Queue
PPT
23 priority queue
PPTX
Deque and its applications
PPT
PPT
Heap sort
PPTX
Ppt presentation of queues
PDF
Quick Sort , Merge Sort , Heap Sort
PPT
Queue Data Structure
PDF
Queue as data_structure
PPT
Queue data structure
PPT
Heapsort
PPT
Notes DATA STRUCTURE - queue
PPTX
My lectures circular queue
Priority queues
Algorithm: priority queue
Priority queue
computer notes - Priority queue
Heaps
Priority Queue
23 priority queue
Deque and its applications
Heap sort
Ppt presentation of queues
Quick Sort , Merge Sort , Heap Sort
Queue Data Structure
Queue as data_structure
Queue data structure
Heapsort
Notes DATA STRUCTURE - queue
My lectures circular queue
Ad

Similar to Heaps & priority queues (20)

PPSX
Unit-5 Advanced tree zxcppt
PPTX
Data structures and algorithms lab10
PPTX
data structures and algorithms Unit 3
PPT
Advanced s and s algorithm.ppt
PPT
FRbsbsvvsvsvbshgsgsvzvsvvsvsvsvsvsvvev.ppt
PPTX
05 heap 20161110_jintaeks
PDF
PPT
Unit III Heaps.ppt
PPTX
Lesson-7-Priority-Queues-and-Heap-Trees-1.pptx
PPT
Heap tree
PDF
Heap Tree.pdf
PDF
Heap, Types of Heap, Insertion and Deletion
PPT
Ch15 Heap
PPTX
Heap_data_structures_in_data_steruc.pptx
PPTX
Array implementation & Construction of Heap
PPT
Stacks, Queues, Deques
PDF
Basic data structures in python
PDF
Sienna 7 heaps
PPT
23 stacks-queues-deques
PDF
Binary Tree - Algorithms
Unit-5 Advanced tree zxcppt
Data structures and algorithms lab10
data structures and algorithms Unit 3
Advanced s and s algorithm.ppt
FRbsbsvvsvsvbshgsgsvzvsvvsvsvsvsvsvvev.ppt
05 heap 20161110_jintaeks
Unit III Heaps.ppt
Lesson-7-Priority-Queues-and-Heap-Trees-1.pptx
Heap tree
Heap Tree.pdf
Heap, Types of Heap, Insertion and Deletion
Ch15 Heap
Heap_data_structures_in_data_steruc.pptx
Array implementation & Construction of Heap
Stacks, Queues, Deques
Basic data structures in python
Sienna 7 heaps
23 stacks-queues-deques
Binary Tree - Algorithms

More from Pedro Hugo Valencia Morales (10)

PPTX
Árboles como Estructura de Datos
PPTX
C++ io manipulation
PDF
Colas de prioridad
PDF
Tema4 programación generica
PDF
Arquitectura ssdd
PDF
PPT
Chapter 1 slides
Árboles como Estructura de Datos
C++ io manipulation
Colas de prioridad
Tema4 programación generica
Arquitectura ssdd
Chapter 1 slides

Heaps & priority queues

  • 2. Overview Array-Based Representation of a Complete Binary Tree Heaps The ADT Priority Queue Heap Implementation of the ADT Priority Queue Heapsort
  • 3. 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:
  • 4. Array-Based Representation of a Binary Tree Bob Mike Sam Tom Pam Joe Sue Ann Jane Mary root 0 free 10
  • 5. 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.
  • 6. Left Child & Right Child in a Complete, Array-Based Binary Tree LeftChild(i) = 2*i + 1 RightChild(i) = 2*i + 2 Bob Mike Sam Tom Pam Joe Sue Ann Jane Mary
  • 7. 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  (i – 1) / 2  Examples: 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
  • 8. Parent in a Complete , Array-Based Binary Tree Parent(i) =  (i – 1) / 2  Bob Mike Sam Tom Pam Joe Sue Ann Jane Mary
  • 9. 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.
  • 10. Array-Based Representation of a Complete Binary Tree Bob Mike Sam Tom Pam Joe Sue Ann Jane Mary
  • 11. 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.
  • 12. Array-Based Representation of a Heap Mary Mike Sam Ann Tom Pam Sue Joe Bob Jane 3 2 1 5 4 7 6 9 8 10
  • 13. 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.
  • 14. 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.
  • 15. PriorityQ: Array-Based Implementation const int MaxItems = 100; // max # items in PriorityQ typedef int KeyType; // 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 ); }
  • 16. PriorityQ: Array-Based Implementation typedef PQItemType HeapItemType; class PriorityQ { public: // declarations of public member functions private: HeapItemType items[MaxItems]; int size; };
  • 17. 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; }
  • 18. 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.
  • 19. 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; }
  • 20. Semiheap A semiheap is a complete binary tree in which the root’s left and right subtrees are both heaps . 10 5 10 40 30 15 50 35 20 55 60 45 25 55 45 25
  • 21. 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.
  • 22. Retrieve & Delete: Example 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. 5 10 40 30 15 50 35 20 55 45 60 25 move 25 to here
  • 23. Rebuilding a Heap: Example (Cont’d.) 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. 15 50 35 20 5 10 40 30 55 45 25 swap 25 with the item in this node
  • 24. Rebuilding a Heap: Example (Cont’d.) 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. 15 50 35 20 5 10 40 30 25 45 55 swap 25 with the item in this node
  • 25. Rebuilding a Heap: Example (Cont’d.) 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. 15 25 35 20 5 10 40 30 50 45 55 swap 25 with the item in this node
  • 26. Rebuilding a Heap: Example (Cont’d.) 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 . 15 40 35 20 5 10 25 30 50 45 55
  • 27. 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 ); } } }
  • 28. 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.
  • 29. PriorityQ Insert: Example 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. 15 40 35 20 5 10 25 30 50 45 55 47
  • 30. PriorityQ Insert: Example (Cont’d.) 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 50 45 55 47
  • 31. PriorityQ Insert: Example (Cont’d.) 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 50 45 55 35
  • 32. PriorityQ Insert: Example (Cont’d.) 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. 15 40 45 20 5 10 25 30 50 47 55 35
  • 33. 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; }
  • 34. 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 .
  • 35. 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 .
  • 36. 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).
  • 37. Transform an Array Into a Heap: Example 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). 7 2 4 10 9 3 5 6 5 4 3 2 1 0 4 2 7 5 3 6 7 6 9 10 rebuildHeap
  • 38. Transform an Array Into a Heap: Example 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. rebuildHeap 9 2 4 10 7 3 5 6 5 4 3 2 1 0 4 2 9 5 3 6 7 6 7 10
  • 39. Transform an Array Into a Heap: Example 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. rebuildHeap 9 2 4 5 7 3 10 6 5 4 3 2 1 0 4 2 9 10 3 6 7 6 7 5
  • 40. Transform an Array Into a Heap: Example 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 . rebuildHeap 3 2 4 5 7 9 10 6 5 4 3 2 1 0 4 2 3 10 9 6 7 6 7 5
  • 41. Transform an Array Into a Heap: Example 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. rebuildHeap 7 2 4 5 3 9 10 6 5 4 3 2 1 0 4 2 7 10 9 6 7 6 3 5
  • 42. Transform an Array Into a Heap: Example 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 9 6 10 5 4 3 2 1 0 4 2 7 6 9 10 7 6 3 5
  • 43. 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.
  • 44. 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 ); }
  • 45. 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 ); } } }
  • 46. 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.
  • 47. 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.
  • 48. Transform a Heap Into a Sorted Array: Example 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]. 7 2 4 5 3 9 6 10 4 2 7 6 9 10 5 4 3 2 1 0 7 6 3 5 a[ ]: Heap
  • 49. Transform a Heap Into a Sorted Array: Example 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 9 6 3 4 2 7 6 9 3 5 4 3 2 1 0 7 6 10 5 a[ ]: Semiheap Sorted rebuildHeap
  • 50. Transform a Heap Into a Sorted Array: Example 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 3 6 9 4 2 7 6 3 9 5 4 3 2 1 0 7 6 10 5 a[ ]: Becoming a Heap Sorted rebuildHeap
  • 51. Transform a Heap Into a Sorted Array: Example 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]. 3 2 4 5 7 6 9 4 2 3 6 7 9 5 4 3 2 1 0 7 6 10 5 a[ ]: Heap Sorted
  • 52. Transform a Heap Into a Sorted Array: Example 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 7 6 5 4 2 3 6 7 5 5 4 3 2 1 0 7 6 10 9 a[ ]: Semiheap Sorted rebuildHeap
  • 53. Transform a Heap Into a Sorted Array: Example 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]. 3 2 4 5 6 7 4 2 3 6 5 7 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted rebuildHeap
  • 54. Transform a Heap Into a Sorted Array: Example 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 5 6 4 7 2 3 6 5 4 5 4 3 2 1 0 7 6 10 9 a[ ]: Semiheap Sorted rebuildHeap
  • 55. Transform a Heap Into a Sorted Array: Example 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]. 3 2 5 4 6 7 2 3 4 5 6 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted
  • 56. Transform a Heap Into a Sorted Array: Example a[0..3] now represents a semiheap. a[4..7] is the sorted region. Invoke rebuildHeap on the semiheap rooted at a[0]. 3 5 4 2 7 6 3 4 5 2 5 4 3 2 1 0 7 6 10 9 a[ ]: Semiheap Sorted rebuildHeap
  • 57. Transform a Heap Into a Sorted Array: Example rebuildHeap is invoked recursively on a[1] to complete the transformation of the semiheap rooted at a[0] into a heap. Becoming a Heap 3 2 4 5 7 6 3 4 2 5 5 4 3 2 1 0 7 6 10 9 a[ ]: Sorted rebuildHeap
  • 58. Transform a Heap Into a Sorted Array: Example 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]. 2 3 4 5 7 6 2 4 3 5 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted
  • 59. Transform a Heap Into a Sorted Array: Example a[0..2] now represents a semiheap. a[3..7] is the sorted region. Invoke rebuildHeap on the semiheap rooted at a[0]. 3 4 2 7 6 5 4 3 2 5 4 3 2 1 0 7 6 10 9 a[ ]: Semiheap Sorted rebuildHeap
  • 60. Transform a Heap Into a Sorted Array: Example 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]. 3 2 4 7 6 5 2 3 4 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted
  • 61. Transform a Heap Into a Sorted Array: Example a[0..1] now represents a semiheap. a[2..7] is the sorted region. Invoke rebuildHeap on the semiheap rooted at a[0]. 3 2 7 6 5 4 3 2 5 4 3 2 1 0 7 6 10 9 a[ ]: Semiheap Sorted rebuildHeap
  • 62. Transform a Heap Into a Sorted Array: Example 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]. 2 3 7 6 5 4 2 3 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted
  • 63. Transform a Heap Into a Sorted Array: Example 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. 2 7 6 5 4 3 2 5 4 3 2 1 0 7 6 10 9 a[ ]: Heap Sorted
  • 64. Transform a Heap Into a Sorted Array: Example Since the sorted region contains all the items in the array, we are done. 7 6 5 4 3 2 5 4 3 2 1 0 7 6 10 9 a[ ]: Sorted
  • 65. 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 ); } }
  • 66. 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).
  • 67. Growth Rates for Selected Sorting Algorithms † 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.