Site Search:

IndexMinPQ.java


/*
 * 
 * Indexed Priority Queue.
 * supports change node i's priority keys[i] and delete node i.
 * time: O(NlogN)
 * space: O(N)
 */
public class IndexMinPQ<Key extends Comparable<Key>> {
    public static int[] arr = {3, 2, 4, 1, 8, 5, 0};
    private int N;       //number of elements on PQ
    private int[] pq;     //binary heap using 1-based indexing
    private int[] qp;      //inverse: qp[pq[i]] = pq[qp[i]] = i
    private Key[] keys;    //items with priorities
    
    public IndexMinPQ(int maxN) {
        keys = (Key[]) new Comparable[maxN + 1];
        pq = new int[maxN + 1];
        qp = new int[maxN + 1];
        for(int i = 0; i <= maxN; i++) qp[i] = -1;
    }
    
    public boolean isEmpty() {
        return N == 0;
    }
    
    public boolean contains(int k) {
        return qp[k] != -1;
    }
    
    public void insert(int k, Key key) {
        N++;
        qp[k] = N;
        pq[N] = k;
        keys[k] = key;
        swim(N);
    }
    
    public Key min() {
        return keys[pq[1]];
    }
    
    public int delMin() {
        int indexOfMin = pq[1];
        exch(1, N--);
        sink(1);
        keys[pq[N+1]] = null;
        qp[pq[N+1]] = -1;
        return indexOfMin;
    }
    
    public int minIndex() {
        return pq[1];
    }
    
    public void change(int k, Key key) {
        keys[k] = key;
        swim(qp[k]);
        sink(qp[k]);
    }
    
    public void delete(int k) {
        exch(k, N--);
        swim(qp[k]);
        sink(qp[k]);
        keys[pq[N+1]] = null;
        qp[pq[N+1]] = -1;
    }
    
    private void sink(int k) {
        while(2*k <= N) {
            int j = 2*k;
            if(j < N && greater(keys[pq[j]], keys[pq[j+1]])) j++;
            if(!greater(keys[pq[k]], keys[pq[j]])) break;
            exch(k, j);
            k = j;
        }
    }
    
    private void swim(int k) {
        while(k > 1 && greater(keys[pq[k/2]], keys[pq[k]])) {
            exch(k/2, k);
            k = k/2;
        }
    }
    
    private void exch(int i, int j) {
        Key tmp = keys[pq[i]];
        keys[pq[i]] = keys[pq[j]];
        keys[pq[j]] = tmp;
    }
    
    private boolean greater(Key key1, Key key2) {
        return key1.compareTo(key2) > 0;
    }
    
    public static void main(String[] args) {
        IndexMinPQ<Integer> impq = new IndexMinPQ<Integer>(arr.length);
        
        for (int i = 0; i < arr.length; i++) {
            impq.insert(i+1, new Integer(arr[i]));  //in graph, i is node (skip 0), arr[i] is shortest path to node i
        }
        
        while(!impq.isEmpty()) {
            System.out.println(impq.min());
            int minIndex = impq.delMin();
            //System.out.println("delMin Index: " + minIndex);
        }
        
        System.out.println("change index 2 to 1000");
        for (int i = 0; i < arr.length; i++) {
            impq.insert(i+1, new Integer(arr[i]));
        }
//        printArray(impq);
        
        System.out.println(impq.contains(2));
        impq.change(2, 10000);
//        printArray(impq);
        while(!impq.isEmpty()) {
            System.out.println(impq.min());
            int minIndex = impq.delMin();
//            System.out.println("delMin Index: " + minIndex);
//            printArray(impq);
            
        }
        
        System.out.println("delete key at index 2");
        for (int i = 0; i < arr.length; i++) {
            impq.insert(i+1, new Integer(arr[i]));
        }
        
        System.out.println(impq.contains(2));
        impq.delete(2);
        while(!impq.isEmpty()) {
            System.out.println(impq.min());
            int minIndex = impq.delMin();
            //System.out.println("delMin Index: " + minIndex);
        }
    }
    
    public static void printArray(IndexMinPQ impq) {
        System.out.println("====================");
        System.out.println("pq:");
        for(int i = 0; i < impq.pq.length; i++) {
            System.out.print("pq[" + i + "] = " + impq.pq[i] + ",");
        }
        System.out.println("qp:");
        for(int i = 0; i < impq.qp.length; i++) {
            System.out.print("qp[" + i + "] = " + impq.qp[i] + ",");
        }
        System.out.println("keys:");
        for(int i = 0; i < impq.keys.length; i++) {
            System.out.print("keys[" + i + "] = " + impq.keys[i] + ",");
        }
        System.out.println("====================");
    }
}