I am trying to determine the correctness of a helper method within my MaxHeap class.
The goal of this helper method is, given the index of any node in the Max Heap, sink it to the correct level in the heap so that all of its children are greater than the node, and its parent is greater (essentially sink it to the correct position to regain the key property of a Max Heap). Max-heap property we don't want to break: the value of each node is less than or equal to the value of its parent
I implemented this first without looking at solution code provided online/in a MOOC course. The solution code is very (too) compact and am having trouble determining if my solution is also correct.
My heap representation is an array, pq[], with empty index 0. Heap will be from position 1 to pq.length -1. for a node at position nodeIndex, left child will be at index 2k and right child at index 2k + 1.
private void sink(int nodeIndex){
/*
* children of nodeIndex are in positions 2k, and 2k+1. Here we iterate while the node we are trying to sink, nodeIndex, has a left child.
*
* Note: if node has a right child it WILL have a left child because we are dealing with a Complete tree, meaning leaf nodes are left leaning
*/
while(2 * nodeIndex <= this.top){
//initially, we have not checked if node we are sinking has a right child, so we say left child is the node with the greatest Key for now
int indexOfMaxChild = 2 * nodeIndex;
//simple arithmetic to see which indexis would contain left and right child (if right child exists)
int indexOfLeftChild = 2 * nodeIndex;
int indexOfRightChild = indexOfLeftChild+ 1;
//if nodeIndex has a right child
if(indexOfRightChild <= this.top) {
//helper method that returns the position/index of nodeIndex's children with the greatest key. If children 1's key is < than children 2's key, return the index of children 2, otherwise, return index of children 1
indexOfMaxChild = indexOfMaxKey(indexOfLeftChild, indexOfRightChild);
}
// if nodeIndex is less than child with greatest key, swap (sink by one level)
if(isLessThan(nodeIndex, indexOfMaxChild))
exchange(nodeIndex, indexOfMaxChild);
else //if node we are trying to sink is at the correct level, no sinking needed
break;
// we update the index of the node we are sinking and repeat if it has a left child
nodeIndex = indexOfMaxChild;
}
}
Solution code:
private void sink(int k) { while (2*k <= top) { int j = 2*k; if (j < top && less(j, j+1)) j++; if (!less(k, j)) break; exch(k, j); k = j; } }