chapter 11: priority queues and heaps
DESCRIPTION
CHAPTER 11: Priority Queues and Heaps. Java Software Structures: Designing and Using Data Structures Third Edition John Lewis & Joseph Chase. Chapter Objectives. Define a heap abstract data structure Demonstrate how a heap can be used to solve problems Examine various heap impmentations - PowerPoint PPT PresentationTRANSCRIPT
© 2010 Pearson Addison-Wesley. All rights reserved.
Addison Wesley is an imprint of
CHAPTER 11: Priority Queues and Heaps
Java Software Structures:Designing and Using Data Structures
Third Edition
John Lewis & Joseph Chase
1-2
© 2010 Pearson Addison-Wesley. All rights reserved. 1-2
Chapter Objectives
• Define a heap abstract data structure• Demonstrate how a heap can be used to
solve problems• Examine various heap impmentations• Compare heap implementations
1-3
© 2010 Pearson Addison-Wesley. All rights reserved. 1-3
Heaps
• A heap is a binary tree with two added properties:– It is a complete tree– For each node, the node is less than or equal
to both the left child and the right child
• This definition describes a minheap
1-4
© 2010 Pearson Addison-Wesley. All rights reserved. 1-4
Heaps
• In addition to the operations inherited from a binary tree, a heap has the following additional operations:– addElement – removeMin– findMin
1-5
© 2010 Pearson Addison-Wesley. All rights reserved. 1-5
The operations on a heap
1-6
© 2010 Pearson Addison-Wesley. All rights reserved. 1-6
The HeapADT/** * HeapADT defines the interface to a Heap. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 9/9/2008 */ package jss2; public interface HeapADT<T> extends BinaryTreeADT<T> { /** * Adds the specified object to this heap. * * @param obj the element to added to this head */ public void addElement (T obj);
/** * HeapADT defines the interface to a Heap. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 9/9/2008 */ package jss2; public interface HeapADT<T> extends BinaryTreeADT<T> { /** * Adds the specified object to this heap. * * @param obj the element to added to this head */ public void addElement (T obj);
1-7
© 2010 Pearson Addison-Wesley. All rights reserved. 1-7
The HeapADT (continued) /** * Removes element with the lowest value from this heap. * * @return the element with the lowest value from this heap */ public T removeMin(); /** * Returns a reference to the element with the lowest value in * this heap. * * @return a reference to the element with the lowest value in this heap */ public T findMin();}
/** * Removes element with the lowest value from this heap. * * @return the element with the lowest value from this heap */ public T removeMin(); /** * Returns a reference to the element with the lowest value in * this heap. * * @return a reference to the element with the lowest value in this heap */ public T findMin();}
1-8
© 2010 Pearson Addison-Wesley. All rights reserved. 1-8
UML description of the HeapADT
1-9
© 2010 Pearson Addison-Wesley. All rights reserved. 1-9
The addElement Operation
• The addElement method adds a given element to the appropriate location in the heap
• The proper location is the one location that will maintain the completeness of the tree
1-10
© 2010 Pearson Addison-Wesley. All rights reserved. 1-10
The addElement Operation
• There is only one correct location for the insertion of a new node– Either the next open position from the left at
level h– Or the first position in level h+1 if level h is full
1-11
© 2010 Pearson Addison-Wesley. All rights reserved. 1-11
The addElement Operation
• Once we have located the new node in the proper position, then we must account for the ordering property
• We simply compare the new node to its parent value and swap the values if necessary
• We continue this process up the tree until either the new value is greater than its parent or the new value becomes the root of the heap
1-12
© 2010 Pearson Addison-Wesley. All rights reserved. 1-12
Two minheaps containing the same data
1-13
© 2010 Pearson Addison-Wesley. All rights reserved. 1-13
Insertion points for a heap
1-14
© 2010 Pearson Addison-Wesley. All rights reserved. 1-14
Insertion and reordering in a heap
1-15
© 2010 Pearson Addison-Wesley. All rights reserved. 1-15
The removeMin Operation
• The removeMin method removes the minimum element from the heap
• The minimum element is always stored at the root
• Thus we have to return the root element and replace it with another element
1-16
© 2010 Pearson Addison-Wesley. All rights reserved. 1-16
The removeMin Operation
• The replacement element is always the last leaf
• The last leaf is always the last element at level h
1-17
© 2010 Pearson Addison-Wesley. All rights reserved. 1-17
Examples of the last leaf in a heap
1-18
© 2010 Pearson Addison-Wesley. All rights reserved. 1-18
The removeMin Operation
• Once the element stored in the last leaf has been moved to the root, the heap will have to reordered
• This is accomplished by comparing the new root element to the smaller of its children and swapping them if necessary
• This process is repeated down the tree until the element is either in a leaf or is less than both of its children
1-19
© 2010 Pearson Addison-Wesley. All rights reserved. 1-19
Removal and reordering in a heap
1-20
© 2010 Pearson Addison-Wesley. All rights reserved. 1-20
Using Heaps: Priority Queue
• A priority queue is a collection that follows two ordering rules:– Items which have higher priority go first– Items with the same priority use a first in, first out
method to determine their ordering
• A priority queue could be implemented using a list of queues where each queue represents items of a given priority
1-21
© 2010 Pearson Addison-Wesley. All rights reserved. 1-21
Using Heaps: Priority Queue
• Another solution is to use a minheap• Sorting the heap by priority accomplishes the
first ordering• However, the first in, first out ordering for items
with the same priority has to be manipulated
1-22
© 2010 Pearson Addison-Wesley. All rights reserved. 1-22
Using Heaps: Priority Queue
• The solution is to create a PriorityQueueNode object that stores the element to be placed on the queue, the priority of the element and the arrival order of the element
• Then we simply define a compareTo method for the PriorityQueueNode class that first compares priority then arrival time
• The PriorityQueue class then extends the Heap class and stores PriorityQueueNodes
1-23
© 2010 Pearson Addison-Wesley. All rights reserved. 1-23
The PriorityQueueNode class /** * PriorityQueueNode represents a node in a priority queue containing a * comparable object, order, and a priority value. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 8/19/08 */ public class PriorityQueueNode<T> implements Comparable<PriorityQueueNode>{ private static int nextorder = 0; private int priority; private int order; private T element; /** * Creates a new PriorityQueueNode with the specified data. * * @param obj the element of the new priority queue node * @param prio the integer priority of the new queue node */
/** * PriorityQueueNode represents a node in a priority queue containing a * comparable object, order, and a priority value. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 8/19/08 */ public class PriorityQueueNode<T> implements Comparable<PriorityQueueNode>{ private static int nextorder = 0; private int priority; private int order; private T element; /** * Creates a new PriorityQueueNode with the specified data. * * @param obj the element of the new priority queue node * @param prio the integer priority of the new queue node */
1-24
© 2010 Pearson Addison-Wesley. All rights reserved. 1-24
The PriorityQueueNode class (cont.) public PriorityQueueNode (T obj, int prio) { element = obj; priority = prio; order = nextorder; nextorder++; } /** * Returns the element in this node. * * @return the element contained within this node */ public T getElement() { return element; } /** * Returns the priority value for this node. * * @return the integer priority for this node */
public PriorityQueueNode (T obj, int prio) { element = obj; priority = prio; order = nextorder; nextorder++; } /** * Returns the element in this node. * * @return the element contained within this node */ public T getElement() { return element; } /** * Returns the priority value for this node. * * @return the integer priority for this node */
1-25
© 2010 Pearson Addison-Wesley. All rights reserved. 1-25
The PriorityQueueNode class (cont.) public int getPriority() { return priority; } /** * Returns the order for this node. * * @return the integer order for this node */ public int getOrder() { return order; } /** * Returns a string representation for this node. * */ public String toString() { String temp = (element.toString() + priority + order); return temp; }
public int getPriority() { return priority; } /** * Returns the order for this node. * * @return the integer order for this node */ public int getOrder() { return order; } /** * Returns a string representation for this node. * */ public String toString() { String temp = (element.toString() + priority + order); return temp; }
1-26
© 2010 Pearson Addison-Wesley. All rights reserved. 1-26
The PriorityQueueNode class (cont.) /** * Returns the 1 if the current node has higher priority than * the given node and -1 otherwise. * * @param obj the node to compare to this node * @return the integer result of the comparison of the obj node and this * this one */ public int compareTo(PriorityQueueNode obj) { int result; PriorityQueueNode<T> temp = obj; if (priority > temp.getPriority()) result = 1; else if (priority < temp.getPriority()) result = -1; else if (order > temp.getOrder()) result = 1; else result = -1; return result; }}
/** * Returns the 1 if the current node has higher priority than * the given node and -1 otherwise. * * @param obj the node to compare to this node * @return the integer result of the comparison of the obj node and this * this one */ public int compareTo(PriorityQueueNode obj) { int result; PriorityQueueNode<T> temp = obj; if (priority > temp.getPriority()) result = 1; else if (priority < temp.getPriority()) result = -1; else if (order > temp.getOrder()) result = 1; else result = -1; return result; }}
1-27
© 2010 Pearson Addison-Wesley. All rights reserved. 1-27
The PriorityQueue class/** * PriorityQueue demonstrates a priority queue using a Heap. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 8/19/08 */ import jss2.*; public class PriorityQueue<T> extends ArrayHeap<PriorityQueueNode<T>>{ /** * Creates an empty priority queue. */ public PriorityQueue() { super(); }
/** * PriorityQueue demonstrates a priority queue using a Heap. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 8/19/08 */ import jss2.*; public class PriorityQueue<T> extends ArrayHeap<PriorityQueueNode<T>>{ /** * Creates an empty priority queue. */ public PriorityQueue() { super(); }
1-28
© 2010 Pearson Addison-Wesley. All rights reserved. 1-28
The PriorityQueue class (continued) /** * Adds the given element to this PriorityQueue. * * @param object the element to be added to the priority queue * @param priority the integer priority of the element to be added */ public void addElement (T object, int priority) { PriorityQueueNode<T> node = new PriorityQueueNode<T> (object, priority);
super.addElement(node); } /** * Removes the next highest priority element from this priority * queue and returns a reference to it. * * @return a reference to the next highest priority element in this queue */ public T removeNext() { PriorityQueueNode<T> temp = (PriorityQueueNode<T>)super.removeMin(); return temp.getElement(); }}
/** * Adds the given element to this PriorityQueue. * * @param object the element to be added to the priority queue * @param priority the integer priority of the element to be added */ public void addElement (T object, int priority) { PriorityQueueNode<T> node = new PriorityQueueNode<T> (object, priority);
super.addElement(node); } /** * Removes the next highest priority element from this priority * queue and returns a reference to it. * * @return a reference to the next highest priority element in this queue */ public T removeNext() { PriorityQueueNode<T> temp = (PriorityQueueNode<T>)super.removeMin(); return temp.getElement(); }}
1-29
© 2010 Pearson Addison-Wesley. All rights reserved. 1-29
Implementing Heaps with Links
• A linked implementation of a minheap would simply be an extension of our LinkedBinaryTree class
• However, since we need each node to have a parent pointer, we will create a HeapNode class to extend our BinaryTreeNode class we used earlier
1-30
© 2010 Pearson Addison-Wesley. All rights reserved. 1-30
The HeapNode class/** * HeapNode creates a binary tree node with a parent pointer for use * in heaps. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 9/9/2008 */package jss2;public class HeapNode<T> extends BinaryTreeNode<T>{ protected HeapNode<T> parent; /** * Creates a new heap node with the specified data. * * @param obj the data to be contained within the new heap nodes */ HeapNode (T obj) { super(obj); parent = null; }}
/** * HeapNode creates a binary tree node with a parent pointer for use * in heaps. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 9/9/2008 */package jss2;public class HeapNode<T> extends BinaryTreeNode<T>{ protected HeapNode<T> parent; /** * Creates a new heap node with the specified data. * * @param obj the data to be contained within the new heap nodes */ HeapNode (T obj) { super(obj); parent = null; }}
1-31
© 2010 Pearson Addison-Wesley. All rights reserved. 1-31
Implementing Heaps with Links
• The addElement method must accomplish three tasks:– Add the new node at the appropriate location– Reorder the heap– Reset the lastNode pointer to point to the new
last node
1-32
© 2010 Pearson Addison-Wesley. All rights reserved. 1-32
LinkedHeap/** * Heap implements a heap. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 9/9/2008 */ package jss2;import jss2.exceptions.*; public class LinkedHeap<T> extends LinkedBinaryTree<T> implements HeapADT<T> { public HeapNode<T> lastNode; public LinkedHeap() { super(); }
/** * Heap implements a heap. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 9/9/2008 */ package jss2;import jss2.exceptions.*; public class LinkedHeap<T> extends LinkedBinaryTree<T> implements HeapADT<T> { public HeapNode<T> lastNode; public LinkedHeap() { super(); }
1-33
© 2010 Pearson Addison-Wesley. All rights reserved. 1-33
LinkedHeap - addElement /** * Adds the specified element to this heap in the appropriate * position according to its key value. Note that equal elements * are added to the right. * * @param obj the element to be added to this head */ public void addElement (T obj) { HeapNode<T> node = new HeapNode<T>(obj); if (root == null) root=node; else { HeapNode<T> next_parent = getNextParentAdd(); if (next_parent.left == null) next_parent.left = node; else next_parent.right = node; node.parent = next_parent; } lastNode = node; count++; if (count>1) heapifyAdd(); }
/** * Adds the specified element to this heap in the appropriate * position according to its key value. Note that equal elements * are added to the right. * * @param obj the element to be added to this head */ public void addElement (T obj) { HeapNode<T> node = new HeapNode<T>(obj); if (root == null) root=node; else { HeapNode<T> next_parent = getNextParentAdd(); if (next_parent.left == null) next_parent.left = node; else next_parent.right = node; node.parent = next_parent; } lastNode = node; count++; if (count>1) heapifyAdd(); }
1-34
© 2010 Pearson Addison-Wesley. All rights reserved. 1-34
LinkedHeap - the addElement Operation
• The addElement operation makes use of two private methods:– getNextParentAdd that returns a reference to
the node that will be the parent of the new node
– heapifyAdd that reorders the heap after the insertion
1-35
© 2010 Pearson Addison-Wesley. All rights reserved. 1-35
LinkedHeap - getNextParentAdd /** * Returns the node that will be the parent of the new node * * @return the node that will be a parent of the new node */ private HeapNode<T> getNextParentAdd() { HeapNode<T> result = lastNode; while ((result != root) && (result.parent.left != result)) result = result.parent; if (result != root) if (result.parent.right == null) result = result.parent; else { result = (HeapNode<T>)result.parent.right; while (result.left != null) result = (HeapNode<T>)result.left; } else while (result.left != null) result = (HeapNode<T>)result.left; return result; }
/** * Returns the node that will be the parent of the new node * * @return the node that will be a parent of the new node */ private HeapNode<T> getNextParentAdd() { HeapNode<T> result = lastNode; while ((result != root) && (result.parent.left != result)) result = result.parent; if (result != root) if (result.parent.right == null) result = result.parent; else { result = (HeapNode<T>)result.parent.right; while (result.left != null) result = (HeapNode<T>)result.left; } else while (result.left != null) result = (HeapNode<T>)result.left; return result; }
1-36
© 2010 Pearson Addison-Wesley. All rights reserved. 1-36
LinkedHeap - heapifyAdd /** * Reorders this heap after adding a node. */ private void heapifyAdd() { T temp; HeapNode<T> next = lastNode; temp = next.element; while ((next != root) && (((Comparable)temp).compareTo (next.parent.element) < 0)) { next.element = next.parent.element; next = next.parent; } next.element = temp; }
/** * Reorders this heap after adding a node. */ private void heapifyAdd() { T temp; HeapNode<T> next = lastNode; temp = next.element; while ((next != root) && (((Comparable)temp).compareTo (next.parent.element) < 0)) { next.element = next.parent.element; next = next.parent; } next.element = temp; }
1-37
© 2010 Pearson Addison-Wesley. All rights reserved. 1-37
LinkedHeap - the removeMin Operation
• The removeMin operation must accomplish three tasks:– Replace the element stored in the root with the
element stored in the last leaf– Reorder the heap if necessary– Return the original root element
1-38
© 2010 Pearson Addison-Wesley. All rights reserved. 1-38
LinkedHeap - removeMin /** * Remove the element with the lowest value in this heap and * returns a reference to it. Throws an EmptyCollectionException * if the heap is empty. * * @return the element with the lowest value in * this heap * @throws EmptyCollectionException if an empty collection exception occurs */ public T removeMin() throws EmptyCollectionException { if (isEmpty()) throw new EmptyCollectionException ("Empty Heap"); T minElement = root.element; if (count == 1) { root = null; lastNode = null; } else {
/** * Remove the element with the lowest value in this heap and * returns a reference to it. Throws an EmptyCollectionException * if the heap is empty. * * @return the element with the lowest value in * this heap * @throws EmptyCollectionException if an empty collection exception occurs */ public T removeMin() throws EmptyCollectionException { if (isEmpty()) throw new EmptyCollectionException ("Empty Heap"); T minElement = root.element; if (count == 1) { root = null; lastNode = null; } else {
1-39
© 2010 Pearson Addison-Wesley. All rights reserved. 1-39
LinkedHeap – removeMin (cont.)
HeapNode<T> next_last = getNewLastNode(); if (lastNode.parent.left == lastNode) lastNode.parent.left = null; else lastNode.parent.right = null; root.element = lastNode.element; lastNode = next_last; heapifyRemove(); } count--; return minElement; }
HeapNode<T> next_last = getNewLastNode(); if (lastNode.parent.left == lastNode) lastNode.parent.left = null; else lastNode.parent.right = null; root.element = lastNode.element; lastNode = next_last; heapifyRemove(); } count--; return minElement; }
1-40
© 2010 Pearson Addison-Wesley. All rights reserved. 1-40
LinkedHeap - the removeMin Operation
• Like the addElement operation, the removeMin operation makes use of two private methods– getNewLastNode that returns a reference to
the new last node in the heap– heapifyRemove that reorders the heap after
the removal
1-41
© 2010 Pearson Addison-Wesley. All rights reserved. 1-41
LinkedHeap – getNewLastNode
/** * Returns the node that will be the new last node after a remove. * * @return the node that willbe the new last node after a remove */ private HeapNode<T> getNewLastNode() { HeapNode<T> result = lastNode; while ((result != root) && (result.parent.left == result)) result = result.parent; if (result != root) result = (HeapNode<T>)result.parent.left; while (result.right != null) result = (HeapNode<T>)result.right; return result; }
/** * Returns the node that will be the new last node after a remove. * * @return the node that willbe the new last node after a remove */ private HeapNode<T> getNewLastNode() { HeapNode<T> result = lastNode; while ((result != root) && (result.parent.left == result)) result = result.parent; if (result != root) result = (HeapNode<T>)result.parent.left; while (result.right != null) result = (HeapNode<T>)result.right; return result; }
1-42
© 2010 Pearson Addison-Wesley. All rights reserved. 1-42
LinkedHeap – heapifyRemove
/** * Reorders this heap after removing the root element. */ private void heapifyRemove() { T temp; HeapNode<T> node = (HeapNode<T>)root; HeapNode<T> left = (HeapNode<T>)node.left; HeapNode<T> right = (HeapNode<T>)node.right; HeapNode<T> next; if ((left == null) && (right == null)) next = null; else if (left == null) next = right; else if (right == null) next = left; else if (((Comparable)left.element).compareTo(right.element) < 0) next = left; else next = right;
/** * Reorders this heap after removing the root element. */ private void heapifyRemove() { T temp; HeapNode<T> node = (HeapNode<T>)root; HeapNode<T> left = (HeapNode<T>)node.left; HeapNode<T> right = (HeapNode<T>)node.right; HeapNode<T> next; if ((left == null) && (right == null)) next = null; else if (left == null) next = right; else if (right == null) next = left; else if (((Comparable)left.element).compareTo(right.element) < 0) next = left; else next = right;
1-43
© 2010 Pearson Addison-Wesley. All rights reserved. 1-43
LinkedHeap – heapifyRemove (cont.)
temp = node.element; while ((next != null) && (((Comparable)next.element).compareTo (temp) < 0)) { node.element = next.element; node = next; left = (HeapNode<T>)node.left; right = (HeapNode<T>)node.right; if ((left == null) && (right == null)) next = null; else if (left == null) next = right; else if (right == null) next = left; else if (((Comparable)left.element).compareTo(right.element) < 0) next = left; else next = right; } node.element = temp; }
temp = node.element; while ((next != null) && (((Comparable)next.element).compareTo (temp) < 0)) { node.element = next.element; node = next; left = (HeapNode<T>)node.left; right = (HeapNode<T>)node.right; if ((left == null) && (right == null)) next = null; else if (left == null) next = right; else if (right == null) next = left; else if (((Comparable)left.element).compareTo(right.element) < 0) next = left; else next = right; } node.element = temp; }
1-44
© 2010 Pearson Addison-Wesley. All rights reserved. 1-44
Implementing Heaps with Arrays
• An array implementation of a heap may provide a simpler alternative
• In an array implementation, the location of parent and child can always be calculated
• Given that the root is in position 0, then for any given node stored in position n of the array, its left child is in position 2n + 1 and its right child is in position 2(n+1)
• This means that its parent is in position (n-1)/2
1-45
© 2010 Pearson Addison-Wesley. All rights reserved. 1-45
ArrayHeap
/** * ArrayHeap provides an array implementation of a minheap. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 9/9/2008 */ package jss2;import jss2.exceptions.*; public class ArrayHeap<T> extends ArrayBinaryTree<T> implements HeapADT<T> { public ArrayHeap() { super(); }
/** * ArrayHeap provides an array implementation of a minheap. * * @author Dr. Lewis * @author Dr. Chase * @version 1.0, 9/9/2008 */ package jss2;import jss2.exceptions.*; public class ArrayHeap<T> extends ArrayBinaryTree<T> implements HeapADT<T> { public ArrayHeap() { super(); }
1-46
© 2010 Pearson Addison-Wesley. All rights reserved. 1-46
Implementing Heaps with Arrays
• Like the linked version, the addElement operation for an array implementation of a heap must accomplish three tasks:– Add the new node,– Reorder the heap,– Increment the count by one
• The ArrayHeap version of this method only requires one private method, heapifyAdd which reorders the heap after the insertion
1-47
© 2010 Pearson Addison-Wesley. All rights reserved. 1-47
ArrayHeap - addElement
/** * Adds the specified element to this heap in the appropriate * position according to its key value. Note that equal elements * are added to the right. * * @param obj the element to be added to this heap */ public void addElement (T obj) { if (count==tree.length) expandCapacity(); tree[count] =obj; count++; if (count>1) heapifyAdd(); }
/** * Adds the specified element to this heap in the appropriate * position according to its key value. Note that equal elements * are added to the right. * * @param obj the element to be added to this heap */ public void addElement (T obj) { if (count==tree.length) expandCapacity(); tree[count] =obj; count++; if (count>1) heapifyAdd(); }
1-48
© 2010 Pearson Addison-Wesley. All rights reserved. 1-48
ArrayHeap - heapifyAdd
/** * Reorders this heap to maintain the ordering property after * adding a node. */ private void heapifyAdd() { T temp; int next = count - 1; temp = tree[next]; while ((next != 0) && (((Comparable)temp).compareTo (tree[(next-1)/2]) < 0)) { tree[next] = tree[(next-1)/2]; next = (next-1)/2; } tree[next] = temp; }
/** * Reorders this heap to maintain the ordering property after * adding a node. */ private void heapifyAdd() { T temp; int next = count - 1; temp = tree[next]; while ((next != 0) && (((Comparable)temp).compareTo (tree[(next-1)/2]) < 0)) { tree[next] = tree[(next-1)/2]; next = (next-1)/2; } tree[next] = temp; }
1-49
© 2010 Pearson Addison-Wesley. All rights reserved. 1-49
ArrayHeap - the removeMin Operation
• The removeMin operation must accomplish three tasks:– Replace the element stored at the root with the
element stored in the last leaf– Reorder the heap as necessary– Return the original root element
• Like the addElement operation, the removeMin operation makes use of a private method, heapifyRemove to reorder the heap
1-50
© 2010 Pearson Addison-Wesley. All rights reserved. 1-50
ArrayHeap - removeMin
/** * Remove the element with the lowest value in this heap and * returns a reference to it. Throws an EmptyCollectionException if * the heap is empty. * * @return a reference to the element with the * lowest value in this head * @throws EmptyCollectionException if an empty collection exception occurs */ public T removeMin() throws EmptyCollectionException { if (isEmpty()) throw new EmptyCollectionException ("Empty Heap"); T minElement = tree[0]; tree[0] = tree[count-1]; heapifyRemove(); count--; return minElement; }
/** * Remove the element with the lowest value in this heap and * returns a reference to it. Throws an EmptyCollectionException if * the heap is empty. * * @return a reference to the element with the * lowest value in this head * @throws EmptyCollectionException if an empty collection exception occurs */ public T removeMin() throws EmptyCollectionException { if (isEmpty()) throw new EmptyCollectionException ("Empty Heap"); T minElement = tree[0]; tree[0] = tree[count-1]; heapifyRemove(); count--; return minElement; }
1-51
© 2010 Pearson Addison-Wesley. All rights reserved. 1-51
ArrayHeap - heapifyRemove
/** * Reorders this heap to maintain the ordering property. */ private void heapifyRemove() { T temp; int node = 0; int left = 1; int right = 2; int next; if ((tree[left] == null) && (tree[right] == null)) next = count; else if (tree[left] == null) next = right; else if (tree[right] == null) next = left; else if (((Comparable)tree[left]).compareTo(tree[right]) < 0) next = left; else next = right; temp = tree[node];
/** * Reorders this heap to maintain the ordering property. */ private void heapifyRemove() { T temp; int node = 0; int left = 1; int right = 2; int next; if ((tree[left] == null) && (tree[right] == null)) next = count; else if (tree[left] == null) next = right; else if (tree[right] == null) next = left; else if (((Comparable)tree[left]).compareTo(tree[right]) < 0) next = left; else next = right; temp = tree[node];
1-52
© 2010 Pearson Addison-Wesley. All rights reserved. 1-52
ArrayHeap – heapifyRemove (cont.)
while ((next < count) && (((Comparable)tree[next]).compareTo (temp) < 0)) { tree[node] = tree[next]; node = next; left = 2*node+1; right = 2*(node+1); if ((tree[left] == null) && (tree[right] == null)) next = count; else if (tree[left] == null) next = right; else if (tree[right] == null) next = left; else if (((Comparable)tree[left]).compareTo(tree[right]) < 0) next = left; else next = right; } tree[node] = temp; }
while ((next < count) && (((Comparable)tree[next]).compareTo (temp) < 0)) { tree[node] = tree[next]; node = next; left = 2*node+1; right = 2*(node+1); if ((tree[left] == null) && (tree[right] == null)) next = count; else if (tree[left] == null) next = right; else if (tree[right] == null) next = left; else if (((Comparable)tree[left]).compareTo(tree[right]) < 0) next = left; else next = right; } tree[node] = temp; }
1-53
© 2010 Pearson Addison-Wesley. All rights reserved. 1-53
Analysis of Heap Implementations
• The addElement operation is O(log n) for both implementations
• The removeMin operation is O(log n) for both implementations
• The findMin operation is O(1) for both implementations
1-54
© 2010 Pearson Addison-Wesley. All rights reserved. 1-54
Using Heaps: Heap Sort
• Given the ordering property of a heap, it is natural to think of using a heap to sort a list of objects
• One approach would be to simply add all of the objects to a heap and then remove them one at a time in ascending order
1-55
© 2010 Pearson Addison-Wesley. All rights reserved. 1-55
Using Heaps: Heap Sort
• Insertion into a heap is O(log n) for any given node and thus would be O(n log n) for n nodes to build the heap
• However, it is also possible to build a heap in place using an array
• Since we know the relative position of each parent and its children in the array, we simply start with the first non-leaf node in the array, compare it to its children and swap if necessary
1-56
© 2010 Pearson Addison-Wesley. All rights reserved. 1-56
Using Heaps: Heap Sort
• We then work backward in the array until we reach the root
• Since at most, this will require us to make two comparisons for each non-leaf node, this approach is O(n) to build the heap