Ουρές Προτεραιότητας
Ουρά Προτεραιότητας (Priority Queue) Μια συλλογή αντικειμένων που χαρακτηρίζονται από μια συγκρίσιμη προτεραιότητα. Έχει την λογική εικόνα μιας δομής δεδομένων όπου, αντικείμενα εισέρχονται με οποιαδήποτε σειρά, ενώ εξέρχεται πάντα το αντικείμενο με την μεγαλύτερη προτεραιότητα. Βασικές λειτουργίες αποτελούν: insert - Εισαγωγή αντικειμένου στην ουρά προτεραιότητας. getmax - Έξοδος και επιστροφή του αντικειμένου με την μεγαλύτερη προτεραιότητα. changepriority - Αλλαγή προτεραιότητας ενός αντικειμένου. 1 / 19
Σωρός (Heap) Σχεδόν Πλήρες Δυαδικό Δένδρο Ύψος h(n), h(n) = log 2 (n) Κορυφές n(h), 2 h n(h) 2 h+1 1 Διάταξη για κάθε κόμβο n, η προτεραιότητα του είναι μεγαλύτερη από αυτήν των παιδιών του, άρα και των υποδένδρων αυτών. Σχήμα για κάποιο βάθος d, όλα τα φύλλα είναι σε βάθος d ή d-1. όλα τα φύλλα σε βάθος d-1, είναι δεξιότερα των φύλλων σε βάθος d. Υπάρχει το πολύ 1 κόμβος με 1 παιδί. Το παιδί είναι στα αριστερά του πατέρα. Είναι το δεξιότερο φύλλο σε βάθος d 2 / 19
Array-based Heap representation Root A[1] Θέση A[i] Parent at A[i/2], Left Child at A[2i], Right Child at A[2i+1] http://pages.cs.wisc.edu/~vernon/cs367/notes/11.priority-q.html 3 / 19
insert and swim http://pages.cs.wisc.edu/~vernon/cs367/notes/11.priority-q.html 4 / 19
getmax and sink http://pages.cs.wisc.edu/~vernon/cs367/notes/11.priority-q.html 5 / 19
Priority Queue 1 public class PriorityQueue { 2 private Object[] heap; 3 private int size; 4 protected Comparator cmp; 5 6 public PriorityQueue(int capacity) { } 7 8 public PriorityQueue(int capacity, Comparator cmp) { } 9 10 public void insert(object object) { } 11 12 public Object getmax() { } 13 14 private void swim(int i) { } 15 16 private void sink(int i) { } 17 18 private void swap(int i, int j) { } 19 20 public void print() { } 21 22 boolean empty() { } 23 24 public static void main(string args[]) { } 25 26 } 6 / 19
DefaultComparator 1 final class DefaultComparator implements Comparator { 2 3 public int compare(object a, Object b) { 4 return ((Comparable)a).compareTo(b); 5 } 6 7 } 7 / 19
Constructors 1 public PriorityQueue(int capacity) { 2 this(capacity, new DefaultComparator()); 3 } 4 5 public PriorityQueue(int capacity, Comparator cmp) { 6 if (capacity < 1) throw new IllegalArgumentException(); 7 this.heap = new Object[capacity+1]; 8 this.size = 0; 9 this.cmp = cmp; 10 } 8 / 19
empty, print and swap 1 private void swap(int i, int j) { 2 Object tmp = heap[i]; 3 heap[i] = heap[j]; 4 heap[j] = tmp; 5 } 6 7 public void print() { 8 for (int i=1; i<=size; i++){ 9 System.out.print(heap[i]+ ); 10 } 11 System.out.println(); 12 } 13 14 boolean empty(){ 15 return size == 0; 16 } 9 / 19
insert and getmax 1 public void insert(object object) { 2 // Ensure object is not null 3 // Check available space 4 // Place object at the next available position 5 // Let the newly added object swim 6 } 7 8 public Object getmax() { 9 // Ensure not empty 10 // Keep a reference to the root object 11 // Replace root object with the one at rightmost leaf 12 // Dispose the rightmost leaf 13 // Sink the new root element 14 // Return the object removed 15 } 10 / 19
insert and getmax 1 public void insert(object object) { 2 if (object == null) throw new IllegalArgumentException(); 3 4 if (size == heap.length 1) throw new IllegalStateException(); 5 6 heap[++size] = object; 7 8 swim(size); 9 } 10 11 public Object getmax() { 12 if (size == 0) throw new IllegalStateException(); 13 14 Object object = heap[1]; 15 16 if (size > 1) heap[1] = heap[size]; 17 18 heap[size ] = null; 19 20 sink(1); 21 22 return object; 23 } 11 / 19
swim and sink 1 private void swim(int i) { 2 // if i root (i==1) return 3 // find parent 4 // compare parent with child i 5 // if child <= parent return 6 // else swap and i=p 7 } 8 9 private void sink(int i){ 10 // determine left, right child 11 // if 2*i > size, node i is a leaf return 12 // while haven't reached the leafs 13 // Determine the largest child of node i 14 // If the heap condition holds, stop. 15 // Else swap and go on. 16 } 12 / 19
swim and sink 1 private void swim(int i) { 2 while (i > 1) { //if i root (i==1) return 3 int p = i/2; //find parent 4 int result = cmp.compare(heap[i], heap[p]); //compare parent with child 5 if (result <= 0) return; //if child <= parent return 6 7 swap(i, p); //else swap and i=p 8 i = p; 9 } 10 } 11 12 private void sink(int i){ 13 int left = 2*i, right = left+1, max = left; 14 15 while (left <= size) { 16 17 if (right <= size) { 18 max = cmp.compare(heap[left], heap[right]) < 0? right : left; 19 } 20 21 if (cmp.compare(heap[i], heap[max]) >= 0) return; 22 23 swap(i, max); 24 i = max; left = 2*i; right = left+1; max = left; 25 } 26 } 13 / 19
Priority Queue<T> 1 public class PriorityQueue<T> { 2 private T[] heap; 3 private int size; 4 protected Comparator<T> cmp; 5 6 public PriorityQueue(int capacity, Comparator<T> cmp) { } 7 8 public void insert(t object) { } 9 10 public T getmax() { } 11 12 private void swim(int i) { } 13 14 private void sink(int i) { } 15 16 private void swap(int i, int j) { } 17 18 public void print() { } 19 20 boolean empty() { } 21 22 public static void main(string args[]) { } 23 24 } 14 / 19
Comparator<Integer> 1 final class IntegerComparator implements Comparator<Integer> { 2 3 @Override 4 public int compare(integer o1, Integer o2) { 5 if(o1.intvalue() < o2.intvalue()){ 6 return 1; 7 } 8 else if(o1.intvalue() == o2.intvalue()){ 9 return 0; 10 } 11 else{ 12 return 1; 13 } 14 } 15 16 } 15 / 19
Constructors - Generics 1 public PriorityQueue(int capacity, Comparator<T> cmp) { 2 if (capacity < 1) throw new IllegalArgumentException(); 3 4 this.heap = (T []) new Object[capacity+1]; 5 this.size = 0; 6 this.cmp = cmp; 7 } 16 / 19
empty, print and swap - Generics 1 private void swap(int i, int j) { 2 T tmp = heap[i]; 3 heap[i] = heap[j]; 4 heap[j] = tmp; 5 } 6 7 public void print() { 8 for (int i=1; i<=size; i++){ 9 System.out.print(heap[i]+ ); 10 } 11 System.out.println(); 12 } 13 14 boolean empty(){ 15 return size == 0; 16 } 17 / 19
insert and getmax - Generics 1 public void insert(t object) { 2 if (object == null) throw new IllegalArgumentException(); 3 4 if (size == heap.length 1) throw new IllegalStateException(); 5 6 heap[++size] = object; 7 8 swim(size); 9 } 10 11 public T getmax() { 12 if (size == 0) throw new IllegalStateException(); 13 14 T object = heap[1]; 15 16 if (size > 1) heap[1] = heap[size]; 17 18 heap[size ] = null; 19 20 sink(1); 21 22 return object; 23 } 18 / 19
swim and sink - Generics 1 private void swim(int i) { 2 while (i > 1) { //if i root (i==1) return 3 int p = i/2; //find parent 4 int result = cmp.compare(heap[i], heap[p]); //compare parent with child 5 if (result <= 0) return; //if child <= parent return 6 7 swap(i, p); //else swap and i=p 8 i = p; 9 } 10 } 11 12 private void sink(int i){ 13 int left = 2*i, right = left+1, max = left; 14 15 while (left <= size) { 16 17 if (right <= size) { 18 max = cmp.compare(heap[left], heap[right]) < 0? right : left; 19 } 20 21 if (cmp.compare(heap[i], heap[max]) >= 0) return; 22 23 swap(i, max); 24 i = max; left = 2*i; right = left+1; max = left; 25 } 26 } 19 / 19