Drzewo binarne
W Javie istnieje wiele różnych typów struktur danych. Sterta jest oparta na strukturze drzewa zwanej drzewem binarnym . Drzewo binarne składa się z węzłów, z których każdy może mieć maksymalnie 2 węzły podrzędne:

Maks. sterta
Maks. sterta (lub maks. sterta) to kompletne drzewo binarne . Ważną rzeczą jest to, że węzeł nadrzędny MUSI mieć wartość większą lub równą wartości lewego i prawego węzła podrzędnego. Jeśli nie jest to przestrzegane, nie masz maksymalnej sterty. Min sterta, z drugiej strony, jest odwrotna z pierwiastkiem jako najmniejszą wartością, a kolejne węzły zyskują na wartości; każdy węzeł podrzędny ma wartość większą lub równą swojemu rodzicowi. Jest to również kompletne drzewo binarne. Przykładem maksymalnej sterty jest:
Klasa PriorityQueue
Sterty w Javie można zaimplementować przy użyciu klasy PriorityQueue . Kolejki PriorityQueue służą do znalezienia najważniejszego lub najmniej ważnego elementu w kolekcji. Klasę PriorityQueue można znaleźć w pakiecie java.util.package . PriorityQueues muszą być utworzone z obiektów, które są porównywalne, tak aby były umieszczane w określonej kolejności w kolejce. PriorityQueue może mieć komparator, dzięki czemu dokonuje się porównania między obiektami i kolejki utworzonej zgodnie z tym porównaniem. Przykładem jest:
import java.util.Comparator;
import java.util.PriorityQueue;
public class Main
{
public static void main(String[] args) {
// Create PriorityQueue with comparator for ascending order of array length
PriorityQueue intQueue = new PriorityQueue((a,b) -> a - b);
Integer [] array1 = {1, 2, 4, 6, 8, 9};
Integer [] array2 = {3, 6, 9};
Integer [] array3 = {2, 4, 8, 16, 32, 64, 128};
Integer [] array4 = {5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55};
Integer [] array5 = {4};
//Add the array lengths to intQueue
intQueue.add(array1.length);
intQueue.add(array2.length);
intQueue.add(array3.length);
intQueue.add(array4.length);
intQueue.add(array5.length);
//Write out contents of intQueue as stored
while (intQueue.size() != 0) {
System.out.println(intQueue.remove());
}
}
}
Podanie danych wyjściowych:
1
3
6
7
11
W tym przykładzie domyślnym rozmiarem intQueue jest 11, więc nie podano (zwykle jest to pierwszy argument przed komparatorem), a komparator podano jako:
(a,b) -> a - b
Spowoduje to porównanie elementów w intQueue i posortowanie ich według długości tablicy w porządku rosnącym.
Implementacja PriorityQueue w celu utworzenia maksymalnej sterty
Domyślnie klasa PriorityQueue to min sterta bez komparatora. Sterta minimalna jest przeciwieństwem sterty maksymalnej, więc korzeń jest najmniejszą wartością, a kolejne węzły potomne są większe lub równe węzłom głównym i kolejnym węzłom nadrzędnym. Z tego powodu dla maksymalnej sterty konieczne jest użycie reverseOrder() z frameworka Java Collections jako komparatora. Zapewni to, że otrzymamy maksymalną stertę, a nie minimalną stertę. Ta klasa ma przydatne metody, takie jak add() , zawiera() , remove() , poll() i peek() .metoda | Opis | Złożoność czasu |
---|---|---|
dodać (J) | Dodaje element J na końcu drzewa | O(logN) |
usuń (J) | Usuń wartość J z drzewa | NA) |
głosowanie() | Usuwa maksymalny element drzewa | O(logN) |
zerkać() | Zwraca element główny na szczycie drzewa | O(1) |
zawiera (J) | Zwraca true, jeśli J jest w kolejce, false, jeśli nie | NA) |

mport java.util.Collections;
import java.util.PriorityQueue;
public class MaxHeap {
public static void writeQueue(PriorityQueue<Integer> priorityQueue)
{
// Write out elements in queue, priorityQueue, and remove them using poll()
while(priorityQueue.size() != 0)
{
System.out.println(priorityQueue.poll());
}
}
public static void writeMaxHeap(PriorityQueue<Integer> priorityQueue)
{
// Write out elements in queue as a max heap - root, left child, right child, etc
for (Integer element : priorityQueue) {
System.out.println(element);
}
}
public static void main(String args[])
{
// Array of numbers to create a max heap array from
int[] theArray = {5, 3, 13, 10, 99, 19, 6, 51, 9};
// theQueue is created
PriorityQueue<Integer> theQueue =
new PriorityQueue<Integer>(Collections.reverseOrder());
// Elements are added to theQueue
for (int i = 0 ; i <theArray.length; ++i)
{
theQueue.add(theArray[i]);
}
// The head or root element (priority element) is printed out
System.out.println("The root value is : " + theQueue.peek());
// Find size of theQueue. Use method size()
Integer s = theQueue.size();
System.out.println("Size of theQueue? " + s);
// All elements of theQueue are printed in terms of parent,
// left child, right child
System.out.println("theQueue written using for loop:");
writeMaxHeap(theQueue);
// Does theQueue contain 10? Use method contains()
boolean b = theQueue.contains(10);
System.out.println("Does theQueue contain 10? " + b);
// Erasing value 10 from array using remove()
theQueue.remove(10);
// All elements of theQueue are printed out and removed.
// Each one is the maximum value left in the queue.
// At the end theQueue will be empty
System.out.println("theQueue written out using poll():");
writeQueue(theQueue);
// Find size of theQueue. Use method size()
s = theQueue.size();
System.out.println("Size of theQueue? " + s);
}
}
Wyjście:
Wartość podstawowa to: 99
Rozmiar kolejki? 9
Kolejka napisana przy użyciu pętli for
99
51
19
13
10
5
6
3
9
Czy kolejka zawiera 10? prawda
Kolejka wypisana za pomocą poll()
99
51
19
13
9
6
5
3
Wielkość kolejki? 0
Max Heapify
Algorytm Max Heapify służy do zapewnienia, że drzewo binarne jest stertą maksymalną. Jeśli jesteśmy w węźle n, a jego węzły potomne, lewy i prawy, również same są maksymalnymi stertami, to świetnie, mamy maksymalną stertę. Jeśli tak nie jest w całym drzewie, nie mamy maksymalnej sterty. Algorytm Max Heapify służy do sortowania drzewa tak, aby było zgodne z zasadami maxheap. Max Heapify działa tylko na jednym węźle. Jeśli wymaga się, aby tablica była tablicą o maksymalnej stercie, wszystkie drzewa podrzędne muszą zostać przekonwertowane na maksymalną stertę przed korzeniem, pojedynczo. Algorytm musi być używany w każdym węźle. Zostanie to zrobione na N/2 węzłach (liście będą zgodne z maksymalnymi wymaganiami sterty). Złożoność czasowa sterty wynosi O(NlogN), a dla jednego węzła na wysokości X złożoność czasowa wynosi O(X). Poniższy kod pokazuje, jak maksymalizować drzewo (tablicę).
public class MaxHeapify
{
public static Integer[] maxHeapify(Integer[ ] array, Integer i)
{
// Create left-child and right-child for the node in question
Integer leftChild = 2 * i + 1;
Integer rightChild = 2 * i + 2;
// Assign maxVal to parent node, i
Integer maxVal = i;
// Set maxVal to greater of the two: node or left-child
if( leftChild < array.length && array[leftChild] > array[maxVal] )
maxVal = leftChild;
// Set maxVal to greater of the two: maxVal or right-child
if( rightChild < array.length && array[rightChild] > array[maxVal] )
maxVal = rightChild;
// Check if maxVal is not equal to parent node, then set parent node to
// maxVal, swap values and then do a maxheapify on maxVal
// which is now the previous parent node
if( maxVal != i )
{
Integer value = array[i];
array[i] = array[maxVal];
array[maxVal] = value;
array = maxHeapify(array, maxVal);
}
return array;
}
public static Integer[] maxHeapCreate(Integer array[])
{
// Call maxHeapify to arrange array in a max heap
Integer [] theNewArr = array;
for( Integer i = array.length/2; i >= 0; i-- )
theNewArr = maxHeapify(array, i);
return theNewArr;
}
public static void main(String[] args)
{
// Create array to be maxheapified, theArray,
// and array, newArray, to write results into, by calling maxheapCreate
// newArray will now be a maxheap
Integer[] theArray = {5, 3, 13, 10, 99, 19, 6, 51, 9};
Integer[ ] newArray = maxHeapCreate(theArray);
// Print out contents of newArray
System.out.println("newArray:");
for(int i = 0; i < newArray.length; ++i)
{
System.out.println(newArray[i]);
}
// Print out labelled contents of newArray
System.out.println(" root : " + newArray[0]);
for (int i = 0; i <= newArray.length/2 - 1; i++) {
System.out.print(" parent node : " + newArray[i] + " left child : " +
newArray[(2*i)+1] + " right child :" + newArray[(2*i)+2]);
System.out.println();
}
}
}
Podanie danych wyjściowych:
nowa tablica:
99
51
19
10
3
13
65
9
korzeń: 99
węzeł nadrzędny: 99 lewe dziecko: 51 prawe dziecko: 19
węzeł nadrzędny: 51 lewe dziecko: 10 prawe dziecko: 3
węzeł nadrzędny: 19 lewe dziecko: 13 prawe dziecko: 6
węzeł nadrzędny: 10 lewe dziecko: 5 prawe dziecko: 9
W tym kodzie tablica jest tworzona i wypełniana liczbami. Tworzona jest druga tablica, newArray , która tym razem będzie zawierała wynik działania metody maxheapCreate , tablicę sterty maksymalnej. Metoda maxHeapCreate jest wywoływana z main i tutaj tworzona jest nowa tablica, theNewArr i wypełniana wynikami maxHeapify . Odbywa się to poprzez zapętlenie ponad połowy rozmiaru tablicy wejściowej. Dla każdego przebiegu pętli wywoływana jest metoda maxHeapify , zaczynając od elementu w środku tablicy i kończąc na pierwszym. Dla każdego wywołania maxHeapify, zostaje znalezione lewe dziecko i prawe dziecko węzła nadrzędnego, i, i przeprowadzane są kontrole, aby znaleźć największy z trzech, definiując to jako maxVal . Jeśli maxVal nie jest równy węzłowi nadrzędnemu, następuje zamiana, tak że węzeł nadrzędny i maxVal są zamienione, a następnie maxHeapify jest ponownie wywoływany tym razem na maxVal i wykonywane są te same kroki, co poprzednio. W końcu utworzona zostanie maksymalna sterta i nie będzie już więcej iteracji do wykonania. Zaktualizowana tablica, array , jest teraz zwracana do main jako newArray , a następnie każdy kolejny element jest drukowany na konsoli. nowa tablicajest teraz maksymalną stertą. Zauważ, że podobnie jak w poprzednim przykładzie przy użyciu PriorityQueue liczby są zapisywane: korzeń, prawe dziecko korzenia jako rodzic, lewe dziecko korzenia jako rodzic, prawe dziecko pierwszego prawego dziecka jako rodzic, lewe dziecko pierwszego lewe dziecko jako rodzic, prawe dziecko pierwszego lewego dziecka jako rodzic, lewe dziecko pierwszego prawego dziecka jako rodzic itp. Są one w nieco innej kolejności niż w przypadku korzystania z PriorityQueue, ponieważ porównanie odbywa się między kolejnymi elementami podczas gdy w przykładzie maxheapify węzeł jest porównywany z dwoma kolejnymi elementami tablicy i zamieniany na największą wartość. Krótko mówiąc, stosowane są dwa różne algorytmy. Oba tworzą maksymalną stertę.
GO TO FULL VERSION