function heapifyDown(array, compare) {

    /*
     * `currentIndex` is used to traverse the array. It starts at the first item
     * in the array and moves towards the last.
     */
    let currentIndex = 0;

    /*
     * This loop continues so long as the current item has at least one child.
     * Because the heap is filled in starting with the left child and then
     * moving to the right, simply checking if a left child is present is enough
     * to continue because we know there is at least one child.
     * 
     * When the current item has no children, we know the entire path there is
     * in the correct state and so we can exit.
     */
    while (hasLeftChild(array, currentIndex)) {

        /*
         * This variable is called `smallerChildIndex` because we want to
         * identify which of the two children contain the smaller value.
         * We can start by assuming this will be the left child and then
         * change it if we discover the right child is actually smaller.
         */
        let smallerChildIndex = getLeftChildIndex(currentIndex);

        // if there is a right child, check that
        if (hasRightChild(array, currentIndex)) {
            let rightChildIndex = getRightChildIndex(currentIndex);

            /*
             * If the right child value should come after the left child value
             * (meaning the `compare()` function returns a value greater than
             * zero), then note that the smaller value is actually in the right
             * child by storing the right child index in `smallerChildIndex`.
             */
            if (compare(array[smallerChildIndex], array[rightChildIndex]) > 0) {
                smallerChildIndex = rightChildIndex;
            }
        }

        /*
         * If the current value should come after the smaller child value, then
         * the two values need to be swapped to be in the correct order.
         */
        if (compare(array[currentIndex], array[smallerChildIndex]) > 0) {
            swap(array, currentIndex, smallerChildIndex);
            
            // move down the tree to the previous location of the smaller child
            currentIndex = smallerChildIndex;
        } else {

            /*
             * If we've reached here then the current and child values are
             * already in the correct order. We can infer that this means
             * the rest of the path down is also in the correct order
             * and so we can safely exit the loop.
             */
            break;
        }
    }

}
Normalizes the heap by starting with the root item and ensuring
the entire heap is in the correct order. This is run after a node is
removed from the heap and the root is replaced with a value, so
the root is most likely incorrect.
@param {Array} array The array to adjust.
@param {Function} compare The comparator to use on values in the array.
@returns {void}
@private