Czytałem API kolekcji Java, priorytetową część kolejki, która jest realizowana przez Josh Blocha i Douga Lea, pracę dwóch maestrów.W implementacji kolejki priorytetów Java usuń przy metodzie, dlaczego przesyła się po odłożeniu?
Java PriorityQueue
jest zaimplementowana z stertą tablicy.
fragmentów kodu są tu od PriorityQueue.java
, Linia 600:
/**
* Removes the ith element from queue.
*
* Normally this method leaves the elements at up to i-1,
* inclusive, untouched. Under these circumstances, it returns
* null. Occasionally, in order to maintain the heap invariant,
* it must swap a later element of the list with one earlier than
* i. Under these circumstances, this method returns the element
* that was previously at the end of the list and is now at some
* position before i. This fact is used by iterator.remove so as to
* avoid missing traversing elements.
*/
private E removeAt(int i) {
// assert i >= 0 && i < size;
modCount++;
int s = --size;
if (s == i) // removed last element
queue[i] = null;
else {
E moved = (E) queue[s];
queue[s] = null;
siftDown(i, moved);
//the code I am asking is below:
if (queue[i] == moved) {
siftUp(i, moved);
if (queue[i] != moved)
return moved;
}
}
return null;
}
Co ja zastanawiałem się, że element przeniesiony, który kiedyś na dnie stosu, powinna być duża jeden sub drzewa z i
. Metoda siftDown
jest uzasadniona, po siftDown
najmniejszy z poddrzewa zostanie podniesiony do pozycji i
.
Pytanie brzmi, czy i
się nie zmienia, to znaczy przeniesiony nadal istnieje po siftDown
, wydaje mi się, że drzewo sub już heapified, to nie musi być siftUp
ponownie.
Dlaczego Josh podnosi je ponownie na sam szczyt?
Mam nadzieję, że ci, którzy przeczytali kod, pomogą!
Dzięki Jim! Duży element z jednej strony sterty może nie być tak duży, jak inne w tej samej warstwie. Myślę, że scenariusz, który opisałeś, mógł się zdarzyć tylko na poziomie liścia. Jeśli siftDown nie zmieni pozycji i ma potomka, siftUp wydaje się nadmiarowy. Czy to jest poprawne? Nadzieję wyjaśniono. – stayclean
Dodaj do poprzedniego komentarza, szczególnie w przypadku implementacji sterty opartej na tablicach, jedynym przypadkiem będą liście. – stayclean
@stayclean: Nie ogranicza się to do poziomu liścia. W większej sterty może się zdarzyć wiele poziomów nad liśćmi. Powinieneś być w stanie skonstruować taki przypadek z kupą, która jest tylko o jeden poziom głębszy niż mój przykład. –