800 likes | 809 Views
A queue that prioritizes elements based on their importance value, ensuring more important elements are accessed first. Implements Comparable and Comparator interfaces for element comparison.
E N D
What is it? • It is a queue that access elements according to their importance value. • Eg. A person with broken back should be treated before a person with minor wounds, even though he arrives later. • Printer queue: less page should be selected to print first. But this does not happen in real life.,
Priority • Normally, small value is regarded as more important. • If two item have equal priority, we may allow the item that exists longer in the queue to be more important. • To compare elements, we use Comparable interface or Comparator Interface.
Comparator Interface • Has method: compare(Object o1, Object o2) Has to be the same class or one is the subclass of the other. Return negative value if o1 is less than o2, positive value if o1 is more than o2, and 0 otherwise.
The interface for heap // Postcondition: return the number of items in this priority queue. // Postcondition: return true if this priority queue does not store any item, otherwise return false. // Postcondition: element is added to priority queue.
// Precondition: must not be an empty queue, otherwise it throws NoSuchElementException. // Postcondition: return the most important object from this PriorityQueue. // Precondition: must not be an empty queue, otherwise it throws NoSuchElementException. // Postcondition: remove and return the most important object from this PriorityQueue.
Many implementation choices exist • Normal queue: no priority then? • Array of queue (each queue for each priority): too much space to prepare if there are lots of possible priority.
Use ArrayList • Easy to put members in order right away. • Takes time to find a position to insert though. • Many array elements have to be shifted after insertion or deletion. • getMin is constant time because we can return the first array element right away. • Add and remove take linear time, which is rather slow. We want better time.
Use LinkedList • getMin and removeMin take constant time bacause we can return the front of the list right away. • Add takes linear time, still need to search the position to add, but does not need element shifting. • Remove takes constant time because we can just update pointers.
Linked List priority queue Use Comparable by default
public LinkedPQ (Comparator comp) { this(); comparator = comp; } // constructor with Comparator parameter publicint size( ) { return list.size( ); } // method size public Object getMin ( ) { return list.getFirst( ); } // method getMin List methods in this chapter comes from LinkedList class in Java.
public ObjectremoveMin( ) { return list.removeFirst( ); } // method removeFirst
Wanna add this 3 When loop fails 1 2 4 5 itr.next() returns 4 and it moves. itr.add(element): The element is inserted immediately before the next element that would be returned by next, if any. So using itr.add(element) will insert in the wrong place. Therefore we need to call previous().
protected int compare (Object elem1, Object elem2) { return (comparator==null ? ((Comparable)elem1).compareTo(elem2) : comparator.compare (elem1, elem2)); } // method compare If comparator = null, returnelem1.compareTo (elem2); Otherwise, returncomparator.compare (elem1, elem2);
An implementation using set Real structure is a tree. Use comparator too.
public void add (Object element) { set.add (element); } // method add public Object getMin ( ) { return set.first( ); } // method getMin public Object removeMin ( ) { Object temp = set.first( ); set.remove (set.first( )); return temp; } // method removeMin worstTime(n)for all thesemethods = O(log n).
Implement using real Heap public class Heap implements PriorityQueue{
Heap is a complete binary tree • It is either an empty tree, or • A tree that hasits minimum value in its root. (this kind of heap is called minHeap) • Left and right subtree have to be heaps too. • Heap is not a binary search tree!
26 40 31 48 50 85 36 107 48 55 57 88 Complete binary tree can be put into array It is easy to find child, parent. This is actually the tree from the previous page.
// constructor receives string as input. toString should be implemented. // Postcondition:return integer that < 0, = 0, or > 0, depending on student’s GPA.
Let us see the class for heap. Actual implementation is array.
// Postcondition: element is added to the heap. // worst case time = O(n) // average time = constant Depends on avarage time of percolateUp Resize array, this is O(n) The real operation. //add element to the back.
Percolate up is Swapping 30 with its parent until parent has less value. We will get a heap when we finish.
// Postcondition: movethe last element up the tree. The worst time is O(log n). The average time is constant. protected void percolateUp() { int parent; int child = size-1; Object temp; while (child>0) { parent = (child-1)/2; if(compare(heap[parent],heap[child]) <=0) break; temp = heap[parent]; heap[parent] = heap[child]; heap[child] = temp; child = parent; } // while } // method percolateUp Depend on the height of the tree. Worst case happens when we need to swap up to the root.
Average time -percolateUp • Let the new value be around the middle of existing values. • Half array elements have greater value. • This is a complete binary tree, therefore this half are leaves. • Therefore we need to swap only once to get our value to the right place. • This is why it is said to take a constant time.
public Object getMin() { if (size == 0) throw new NoSuchElementException(“Empty”); return heap[0]; } // method getMin
4 4 8 8 5 6 6 5 removeMin() – Be careful! The tree may no longer be a complete binary tree.
// Precondition: must not be an empty queue or it throws NoSuchElementException. // Postcondition: remove the most important value from this queue. This object is returned as pur answer. // worst time = O(log n). Don’t need to do the exact swap. //put the last element into the root. reduce size to prevent access of the array’s back
26 107 48 when removeMin( ) is called, 48 will swap place with 26. Size will be reduced by 1. after that, percolateDown will be called. 30 31 32 50 85 36
PercolateDown is Swapping 48 with its smallest child.We do it until no more swap can be done. We will get a legal heap in the end.
Initially, let “child”be theleft child. protected void percolateDown(int start) { int parent = start; int child = 2*parent+1; Object temp; while (child<size) { if(child<size-1&&compare(heap[child],heap[child+1]) >0) child++; if (compare(heap[parent],heap[child]) <=0) break; temp = heap[child]; heap[child] = heap[parent]; heap[parent] = temp; parent = child; child= 2*parent+1; } // while } // method percolateDown // Postcondition: heaparranged by moving the top element down the tree. Worst and average time is O(log n). Child can’t be the last element because there will be no right child to compare. If right child is smaller, change our “child”.
Try this and print the heap content. See if it is what you expected.
Let’s look • Let’s say we want to compress file without losing any information • Let M be the data that we want to compress. Let its size be 100000 characters. M contains only character a to character e. • Let E be M after compression.
Normally, 1 character needs 16 bit to store. • 100000 character needs 100000x16 bits. • It is useful to know how to reduce the number of bits while maintaining the same information.