private static <E extends Comparable<E>> void heapifyDown(E[] heap, int index, int startIndex, int endIndex) {
		int leftChildIndex = index * 2 + 1 - startIndex;
		int rightChildIndex = index * 2 + 2 - startIndex;
		int swapIndex = index;
		
		// if left child exists and greater than current node
		if (leftChildIndex <= endIndex) {
			if (heap[leftChildIndex].compareTo(heap[swapIndex]) > 0)
				swapIndex = leftChildIndex;

			// if right child exists and greater than current node and left child
			if (rightChildIndex <= endIndex) {
				if (heap[rightChildIndex].compareTo(heap[swapIndex]) > 0)
					swapIndex = rightChildIndex;
			}
		}
		
		if (swapIndex != index) { // swap if necessary
			E temp = heap[index];
			heap[index] = heap[swapIndex];
			heap[swapIndex] = temp;
			
			heapifyDown(heap, swapIndex, startIndex, endIndex); // check next level down
		}
	}