// heap.java // demonstrates heaps // to run this program: C>java HeapApp import java.io.*; import java.util.*; //////////////////////////////////////////////////////////////// class Node { private int identity; private int parent; private double priority; // weight // ------------------------------------------------------------- public Node(double pri, int id, int par) // constructor { priority = pri; identity = id; parent = par; } // ------------------------------------------------------------- public int getIdentity() { return identity; } // ------------------------------------------------------------- public double getPriority() { return priority; } // ------------------------------------------------------------- public void setPriority(double p) { priority = p; } // ------------------------------------------------------------- public int getParent() { return parent; } //------------------------------------------------------------- public void setParent(int p) { parent = p; } //------------------------------------------------------------- } // end class Node //////////////////////////////////////////////////////////////// class VertexHeap { private Node[] heapArray; private int maxSize; // size of array private int currentSize; // number of nodes in array private int[] map; // ------------------------------------------------------------- public VertexHeap(int mx) // constructor { maxSize = mx; currentSize = 0; heapArray = new Node[maxSize]; // create array //create map array map = new int[maxSize]; for(int i = 0; i < map.length; i++) map[i] = -1; } // ------------------------------------------------------------- public int getIndex( int identity ) { return map[identity]; } // ------------------------------------------------------------- public boolean isEmpty() { return currentSize==0; } // ------------------------------------------------------------- public boolean insert(Node newNode) { if(currentSize==maxSize) return false; heapArray[currentSize] = newNode; map[newNode.getIdentity()] = currentSize; //set position in heap trickleUp(currentSize++); return true; } // end insert() // ------------------------------------------------------------- public void trickleUp(int index) { int parent = (index-1) / 2; Node bottom = heapArray[index]; while( index > 0 && heapArray[parent].getPriority() > bottom.getPriority() ) { //swap( map, heapArray[index].getIdentity(), heapArray[parent].getIdentity() ); swap( map, heapArray[index].getIdentity(), bottom.getIdentity()); heapArray[index] = heapArray[parent]; // move it down index = parent; parent = (parent-1) / 2; } // end while swap( map, heapArray[index].getIdentity(), bottom.getIdentity()); heapArray[index] = bottom; } // end trickleUp() // ------------------------------------------------------------- public Node delete() // delete item with max key { // (assumes non-empty list) Node root = heapArray[0]; //for map map[heapArray[0].getIdentity()] = -1; map[heapArray[--currentSize].getIdentity()] = 0; //fix heap heapArray[0] = heapArray[currentSize]; trickleDown(0); return root; } // end remove() // ------------------------------------------------------------- public void trickleDown(int index) { int smallerChild = 0; Node top = heapArray[index]; // save root while(index < currentSize/2) // while node has at { // least one child, int leftChild = 2*index+1; int rightChild = leftChild+1; // find larger child if(rightChild < currentSize && // (rightChild exists?) heapArray[leftChild].getPriority() > heapArray[rightChild].getPriority()) smallerChild = rightChild; else smallerChild = leftChild; // top >= smallerChild? if( top.getPriority() <= heapArray[smallerChild].getPriority() ) break; // shift child up & fix map swap( map, heapArray[smallerChild].getIdentity(), top.getIdentity()); heapArray[index] = heapArray[smallerChild]; index = smallerChild; // go down } // end while heapArray[index] = top; // root to index } // end trickleDown() // ------------------------------------------------------------- public boolean change(int index, double newPriority, int parent) { if(index<0 || index>=currentSize) return false; double oldValue = heapArray[index].getPriority(); // remember old //only change if lower, this is needed for our myWeightedGraph class if( oldValue < newPriority) return false; heapArray[index].setPriority(newPriority); // change to new heapArray[index].setParent( parent ); trickleDown(index); // trickle it down return true; } // end change() // ------------------------------------------------------------- public void displayHeap() { System.out.print("heapArray: "); // array format for(int m=0; m 0) // for each heap item { if(column == 0) // first item in row? for(int k=0; k