1 / 56

CHAPTER 11: Priority Queues and Heaps

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

ewa
Download Presentation

CHAPTER 11: Priority Queues and Heaps

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CHAPTER 11: Priority Queues and Heaps Java Software Structures: Designing and Using Data Structures Third Edition John Lewis & Joseph Chase

  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

  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

  4. Heaps • In addition to the operations inherited from a binary tree, a heap has the following additional operations: • addElement • removeMin • findMin

  5. The operations on a heap

  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);

  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(); }

  8. UML description of the HeapADT

  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

  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

  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

  12. Two minheaps containing the same data

  13. Insertion points for a heap

  14. Insertion and reordering in a heap

  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

  16. The removeMin Operation • The replacement element is always the last leaf • The last leaf is always the last element at level h

  17. Examples of the last leaf in a heap

  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

  19. Removal and reordering in a heap

  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

  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

  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

  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 */

  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 */

  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; }

  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; } }

  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(); }

  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(); } }

  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

  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; } }

  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

  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(); }

  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(); }

  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

  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; }

  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; }

  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

  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 {

  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; }

  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

  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; }

  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;

  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; }

  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

  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(); }

  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

  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(); }

  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; }

  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

  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; }

More Related