1919import java .util .Arrays ;
2020import java .util .Collection ;
2121import java .util .Comparator ;
22+ import java .util .HashMap ;
2223import java .util .Iterator ;
24+ import java .util .Map ;
2325import java .util .NoSuchElementException ;
2426import java .util .function .IntFunction ;
2527import java .util .function .Supplier ;
@@ -72,6 +74,7 @@ public static <T> PriorityQueue<T> usingComparator(
7274 private final int maxSize ;
7375 private final T [] heap ;
7476 private final LessThan <? super T > lessThan ;
77+ private final Map <T , Integer > indexMap = new HashMap <>();
7578
7679 /** Create an empty priority queue of the configured size using the specified {@link LessThan}. */
7780 public PriorityQueue (int maxSize , LessThan <? super T > lessThan ) {
@@ -272,6 +275,7 @@ public final int size() {
272275 public final void clear () {
273276 Arrays .fill (heap , 0 , size + 1 , null );
274277 size = 0 ;
278+ indexMap .clear ();
275279 }
276280
277281 /**
@@ -280,20 +284,21 @@ public final void clear() {
280284 * constant remove time but the trade-off would be extra cost to all additions/insertions)
281285 */
282286 public final boolean remove (T element ) {
283- for (int i = 1 ; i <= size ; i ++) {
284- if (heap [i ] == element ) {
285- heap [i ] = heap [size ];
286- heap [size ] = null ; // permit GC of objects
287- size --;
288- if (i <= size ) {
289- if (!upHeap (i )) {
290- downHeap (i );
291- }
292- }
293- return true ;
287+ Integer idx = indexMap .get (element );
288+ if (idx == null || idx > size || heap [idx ] != element ) return false ;
289+ heap [idx ] = heap [size ];
290+ indexMap .remove (element );
291+ if (idx != size ) {
292+ indexMap .put (heap [idx ], idx );
293+ }
294+ heap [size ] = null ;
295+ size --;
296+ if (idx <= size ) {
297+ if (!upHeap (idx )) {
298+ downHeap (idx );
294299 }
295300 }
296- return false ;
301+ return true ;
297302 }
298303
299304 /**
@@ -320,36 +325,43 @@ public T[] drainToArrayHighestFirst(IntFunction<T[]> newArray) {
320325 return array ;
321326 }
322327
323- private boolean upHeap (int origPos ) {
324- int i = origPos ;
325- T node = heap [i ]; // save bottom node
326- int j = i >>> 1 ;
327- while (j > 0 && lessThan .lessThan (node , heap [j ])) {
328- heap [i ] = heap [j ]; // shift parents down
329- i = j ;
330- j = j >>> 1 ;
331- }
332- heap [i ] = node ; // install saved node
333- return i != origPos ;
328+ protected final void addToHeap (int idx , T element ) {
329+ heap [idx ] = element ;
330+ indexMap .put (element , idx );
334331 }
335332
336- private void downHeap (int i ) {
337- T node = heap [i ]; // save top node
338- int j = i << 1 ; // find smaller child
339- int k = j + 1 ;
340- if (k <= size && lessThan .lessThan (heap [k ], heap [j ])) {
341- j = k ;
333+ protected boolean upHeap (int i ) {
334+ T node = heap [i ];
335+ int j = i ;
336+ while (j > 1 && lessThan .lessThan (node , heap [j >> 1 ])) {
337+ heap [j ] = heap [j >> 1 ];
338+ indexMap .put (heap [j ], j );
339+ j >>= 1 ;
342340 }
343- while (j <= size && lessThan .lessThan (heap [j ], node )) {
344- heap [i ] = heap [j ]; // shift up child
345- i = j ;
346- j = i << 1 ;
347- k = j + 1 ;
348- if (k <= size && lessThan .lessThan (heap [k ], heap [j ])) {
341+ heap [j ] = node ;
342+ indexMap .put (node , j );
343+ return j < i ;
344+ }
345+
346+ protected boolean downHeap (int i ) {
347+ T node = heap [i ];
348+ int j = i ;
349+ int k ;
350+ while ((k = j << 1 ) <= size ) {
351+ if (k < size && lessThan .lessThan (heap [k + 1 ], heap [k ])) {
352+ k ++;
353+ }
354+ if (lessThan .lessThan (heap [k ], node )) {
355+ heap [j ] = heap [k ];
356+ indexMap .put (heap [j ], j );
349357 j = k ;
358+ } else {
359+ break ;
350360 }
351361 }
352- heap [i ] = node ; // install saved node
362+ heap [j ] = node ;
363+ indexMap .put (node , j );
364+ return j > i ;
353365 }
354366
355367 /**
0 commit comments