code: private static void siftDown(int[] heap, int[] reverseIndex, int start, int end, float[] values)
    {
      int root = start;
      while (root * 2 + 1 <= end) {
        int child = root * 2 + 1;
        int swap = root;
        if (values[heap[swap]] > values[heap[child]]) {
          swap = child;
        }
        if (child + 1 <= end && values[heap[swap]] > values[heap[child + 1]]) {
          swap = child + 1;
        }
        if (swap != root) {
          // swap
          int tmp = heap[swap];
          heap[swap] = heap[root];
          heap[root] = tmp;
  
          // heap index from delta index
          reverseIndex[heap[swap]] = swap;
          reverseIndex[heap[root]] = root;
  
          root = swap;
        } else {
          return;
        }
      }
    }
docs: Rebalances the min-heap by pushing values from the top down and simultaneously updating the reverse index
  
  @param heap         min-heap stored as indices into the array of values
  @param reverseIndex reverse index from the array of values into the heap
  @param start        index to start re-balancing from
  @param end          index to stop re-balancing at
  @param values       values stored in the heap