/****************************************************************************** * Compilation: javac BruteIndexMinPQ.java * Execution: java BruteIndexMinPQ * Dependencies: none * * Indexed PQ implementation using an array. * The elements are integers between 0 and n-1. * * Operation Running time * ------------------------- * Construct n * is empty 1 * size 1 * contains 1 * insert 1 * change key 1 * increase key 1 * decrease key 1 * delete min n * min n * ******************************************************************************/ import java.util.NoSuchElementException; /** * The {@code BruteIndexMinPQ} class represents an indexed priority queue of generic keys. * It supports the usual insert and delete-the-minimum * operations, along with delete and change-the-key * methods. In order to let the client refer to keys on the priority queue, * an integer between {\code 0} and {@code maxN-1} * is associated with each key—the client * uses this integer to specify which key to delete or change. * It also supports methods for peeking at the minimum key, * testing if the priority queue is empty, and iterating through * the keys. *

* This implementation uses an array of keys as the underlying data structure. * The is-empty, size, insert, * delete, key-of, change-key, * decrease-key, and increase-key operations take constant time. * The min-key, min-index, and delete-the-minimum * operations take linear time. * Construction takes time proportional to the specified capacity. *

* For additional documentation, see Section 2.4 of * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. * * @author Robert Sedgewick * @author Kevin Wayne * * @param the generic type of key on this priority queue */ public class BruteIndexMinPQ> { private int n; // number of elements on PQ private Key[] keys; // keys[i] = key of element i /** * Initializes an empty indexed priority queue with indices between {@code 0} * and {@code maxN - 1}. * * @param maxN the keys on this priority queue are index from {@code 0} * {@code maxN - 1} * @throws IllegalArgumentException if {@code maxN < 0} */ public BruteIndexMinPQ(int maxN) { keys = (Key[]) new Comparable[maxN]; } /** * Returns true if this priority queue is empty. * * @return {@code true} if this priority queue is empty; * {@code false} otherwise */ public boolean isEmpty() { return n == 0; } /** * Returns the number of keys on this priority queue. * * @return the number of keys on this priority queue */ public int size() { return n; } /** * Returns true if the argument is an index on this priority queue. * * @param i an index * @return {@code true} if {@code i} is an index on this priority queue; * {@code false} otherwise * @throws IllegalArgumentException unless {@code 0 <= i < maxN} */ public boolean contains(int i) { return keys[i] != null; } /** * Associates key with index {@code i}. * * @param i an index * @param key the key to associate with index {@code i} * @throws IllegalArgumentException unless {@code 0 <= i < maxN} * @throws IllegalArgumentException if there already is an item associated * with index {@code i} */ public void insert(int i, Key key) { if (contains(i)) throw new NoSuchElementException("index is already in priority queue"); n++; keys[i] = key; } /** * Removes a minimum key and returns its associated index. * * @return an index associated with a minimum key * @throws NoSuchElementException if this priority queue is empty */ public int delMin() { int min = minIndex(); keys[min] = null; n--; return min; } /** * Returns a minimum key. * * @return a minimum key * @throws NoSuchElementException if this priority queue is empty */ public Key minKey() { int min = minIndex(); return keys[min]; } /** * Returns an index associated with a minimum key. * * @return an index associated with a minimum key * @throws NoSuchElementException if this priority queue is empty */ public int minIndex() { if (n == 0) throw new NoSuchElementException("Priority queue underflow"); int min = -1; for (int i = 0; i < keys.length; i++) { if (keys[i] == null) continue; else if (min == -1) min = i; else if (keys[i].compareTo(keys[min]) < 0) min = i; } return min; } /** * Change the key associated with index {@code i} to the specified value. * * @param i the index of the key to change * @param key change the key assocated with index {@code i} to this key * @throws IllegalArgumentException unless {@code 0 <= i maxN} * @throws NoSuchElementException no key is associated with index {@code i} */ public void changeKey(int i, Key key) { if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue"); keys[i] = key; } /** * Decrease the key associated with index {@code i} to the specified value. * * @param i the index of the key to decrease * @param key decrease the key assocated with index {@code i} to this key * @throws IllegalArgumentException unless {@code 0 <= i < maxN} * @throws IllegalArgumentException if {@code key >= keyOf(i)} * @throws NoSuchElementException no key is associated with index {@code i} */ public void decreaseKey(int i, Key key) { if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue"); if (keys[i].compareTo(key) <= 0) throw new IllegalArgumentException("Calling decreaseKey() with given argument would not strictly decrease the key"); keys[i] = key; } /** * Increase the key associated with index {@code i} to the specified value. * * @param i the index of the key to increase * @param key increase the key assocated with index {@code i} to this key * @throws IllegalArgumentException unless {@code 0 <= i < maxN} * @throws IllegalArgumentException if {@code key <= keyOf(i)} * @throws NoSuchElementException no key is associated with index {@code i} */ public void increaseKey(int i, Key key) { if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue"); if (keys[i].compareTo(key) >= 0) throw new IllegalArgumentException("Calling increaseKey() with given argument would not strictly increase the key"); keys[i] = key; } }