Uploaded by Aa Kk

q10maxheap

advertisement
MaxHeap
Implement a binary (max) heap for storing Comparable objects.
import java.util.ArrayList;
import java.util.NoSuchElementException;
public class BinaryMaxHeap< DataType extends Comparable<DataType> > {
private ArrayList<DataType> arr = new ArrayList<DataType>();
private void swap(int idx1, int idx2)
{ // helper to let us swap the data of two
nodes (at indices idx1 and idx2 in the ArrayList)
DataType temp = arr.get(idx1);
arr.set(idx1, arr.get(idx2));
arr.set(idx2, temp);
}
/////////////////////////////////////////////////////
// returns the peek without removing
public DataType peekMax() {
if (arr.size() > 0) {
return arr.get(0);
}
return null; // if the heap is empty
}
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
// add a new key to the heap
public void add(DataType d) {
arr.add(d); // first add at the end to preserve completeness
int idx = arr.size() - 1; // where we added the data
int pIdx = (idx-1)/2; // index of the parent
while (idx > 0 && arr.get(idx).compareTo(arr.get(pIdx)) > 0) { // while we haven't
reached the root, and idx and pIdx are in the wrong order
swap(idx, pIdx); // swap
idx
= pIdx; // go up
the tree for the next iteration
pIdx = (idx-1)/2;
}
}
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
// remove the max item
public DataType removeMax() {
DataType res = peekMax(); //
store it so we can return later
if (res == null) { // if the heap
is empty
throw new NoSuchElementException();
}
arr.set(0, arr.get(arr.size()-1));
// put the last item in root (to preserve
completeness)
arr.remove(arr.size()-1); //
...and remove it
from the last index
int idx = 0; // idx of the item that might sink down, initially 0 (root)
int lChildIdx = 2 * idx + 1; // its left child
int rChildIdx = 2 * idx + 2; //
its right child
// if the left child is missing, then there's
nothing left to do (the
while (lChildIdx < arr.size()) {
int biggerChildIdx = lChildIdx; // assume lChildIdx is the bigger child
if (rChildIdx < arr.size() && arr.get(rChildIdx).compareTo(arr.get(lChildIdx)) >
0) {
biggerChildIdx = rChildIdx; // if right child exists and is bigger
}
if (arr.get(biggerChildIdx).compareTo(arr.get(idx)) > 0) { // if the bigger
child is bigger than the parent
swap(idx, biggerChildIdx); //
idx = biggerChildIdx;
swap them (sink down the item)
// update the index of the sunk item
lChildIdx = 2 * idx + 1; // and
of its children
rChildIdx = 2 * idx + 2;
} else { //
the item is in the right position so don't sink, and break to leave
the loop
break;
}
}
return res; //
return the max
}
/////////////////////////////////////////////////////
// IGNORE THE REST
public String toString() {
return arr.toString();
}
public static void main(String[] args) {
BinaryMaxHeap<Integer> heap = new BinaryMaxHeap<>();
heap.add(20);
heap.add(1);
heap.add(100);
heap.add(27);
heap.add(50);
heap.add(69);
heap.add(102);
System.out.println(heap); // [102, 50, 100, 1, 27, 20, 69]
while (heap.peekMax() != null) {
System.out.print(heap.removeMax() + " "); // 102 100 69 50 27 20 1
}
}
}
Download