İkili Ağaç
Java'da birçok farklı türde veri yapısı vardır. Yığın , ikili ağaç adı verilen bir ağaç yapısına dayanır . İkili ağaç, her biri en fazla 2 alt düğüme sahip olabilen düğümlerden oluşur: İkili ağaç, 0 ila 2 düğüme sahip olabilen bir ana düğümden oluşur. Bir sol alt düğüme ve/veya bir sağ alt düğüme sahip olabilir veya hiç düğüm olmayabilir. Tam bir ikili ağaçta, dolu olabilen ancak dolu olması gerekmeyen son seviye dışında tüm düğümler doludur. Son seviye, n'inci seviye, 1 ila 2n düğüme sahip olabilir, burada birincisi n = 0'dadır ve köktür.Maksimum Yığın
Max yığın (veya maxheap) tam bir ikili ağaçtır . Bununla ilgili önemli olan şey, üst düğümün sol ve sağ alt düğümlerinkinden daha büyük veya ona eşit bir değere sahip OLMALIDIR. Buna uyulmazsa, maksimum yığınız olmaz. Öte yandan min yığın, değeri artan ardışık düğümlerle en küçük değer olarak kökün tersidir; her alt düğüm, ebeveyninden büyük veya ona eşit bir değere sahiptir. Aynı zamanda tam bir ikili ağaçtır. Maksimum yığına bir örnek: Maksimum yığın bir diziden oluşturulabilir. Bu dizilim bir ağaç olarak düşünülecektir. Bir yığın için, kök (ağacın en üst üst düğümü) n konumunda (dizin) depolanıyorsa, theArray dizisi için theArray[n] olarak tanımlanır. Sol ve sağ alt düğümler bu nedenle sırasıyla Array[2n+1] ve Array[2n+2]' dedir . Maksimum yığın için, kök theArray[0] konumundadır . n düzeyi için, kök n = 0: theArr[n] üst düğümdür theArr[(2*n)+1] sol alt düğümdür theArr[(2*n)+2] sağ alt düğümdürPriorityQueue Sınıfı
Java'daki yığınlar, PriorityQueue Sınıfı kullanılarak uygulanabilir . PriorityQueu'ler, bir koleksiyondaki en önemli veya en az önemli öğeyi bulmak için kullanılır. PriorityQueue sınıfı, java.util.package içinde bulunabilir . PriorityQueues, kuyruğa belirli bir sıraya yerleştirilmeleri için karşılaştırılabilir nesnelerden oluşturulmalıdır. PriorityQueue bir karşılaştırıcıya sahip olabilir, böylece nesneler arasında bir karşılaştırma yapılır ve bu karşılaştırmaya göre sıra oluşturulur. Bir örnek:
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());
}
}
}
Çıktı vermek:
1 3 6 7 11
Bu örnekte, intQueue'nun varsayılan boyutu 11'dir, bu nedenle belirtilmemiştir (genellikle karşılaştırıcıdan önceki ilk argüman) ve karşılaştırıcı şu şekilde verilmiştir:
(a,b) -> a - b
Bu, intQueue'deki öğeler arasında bir karşılaştırma yapacak ve onu artan düzende dizi uzunluklarına göre sıralayacaktır.
Maksimum Yığın Oluşturmak için PriorityQueue Uygulaması
PriorityQueue Sınıfı varsayılan olarak bir karşılaştırıcı olmadan en az öbektir . Min yığın, maksimum yığının tersidir ve bu nedenle kök en küçük değerdir ve ardışık alt düğümler, kök ve sonraki ebeveyn düğümlerinden daha büyük veya ona eşittir. Bu nedenle, maksimum yığın için karşılaştırıcı olarak Java'nın Koleksiyonlar çerçevesinden reverseOrder() işlevinin kullanılması gerekir . Bu, minimum yığın değil, maksimum yığın elde etmemizi sağlayacaktır. Bu Sınıf, add() , include() , remove() , poll() ve peek() gibi yararlı yöntemlere sahiptir .Yöntem | Tanım | Zaman Karmaşıklığı |
---|---|---|
ekle(J) | Ağacın sonuna J öğesini ekler | O(GünlükN) |
kaldır(J) | J değerini ağaçtan kaldır | AÇIK) |
anket() | Ağacın maksimum öğesini kaldırır | O(GünlükN) |
dikizlemek() | Ağacın tepesindeki kök elemanı döndürür | O(1) |
içerir(J) | J kuyruktaysa true, değilse false döndürür. | AÇIK) |
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);
}
}
Çıktı:
99 Kuyruğun Boyutu? 9 theQueue for döngüsü kullanılarak yazılmış 99 51 19 13 10 5 6 3 9 Kuyrukta 10 var mı? true theQueue poll() kullanılarak yazılmıştır 99 51 19 13 9 6 5 3 Kuyruğun Boyutu? 0
Maksimum Yığınlaştırma
Max Heapify algoritması, bir ikili ağacın maksimum yığın olmasını sağlamak için kullanılır. Bir düğümdeysek, n ve onun alt düğümleri, sol ve sağ da maksimum yığınlar, o zaman harika, maksimum yığınımız var. Ağaç boyunca durum böyle değilse, maksimum yığınımız olmaz. Max Heapify algoritması, ağacı maxheap ilkelerine uyacak şekilde sıralamak için kullanılır. Max Heapify yalnızca bir düğümde çalışır. Gereksinim, dizinin bir maksimum yığın dizisi olmasıysa, kökten önce tüm alt ağaçların teker teker maxheap'e dönüştürülmesi gerekir. Algoritma her düğümde kullanılmalıdır. Bu, N/2 düğümlerinde yapılacaktır (yapraklar maksimum yığın gereksinimlerine uyacaktır). Yığının zaman karmaşıklığı O(NlogN)'dir ve X yüksekliğindeki bir düğüm için zaman karmaşıklığı O(X)'dir. Aşağıdaki kod, bir ağacın (bir dizi) nasıl maksimize edileceğini gösterir.
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();
}
}
}
Çıktı vermek:
yeni Dizi:99 51 19 10 3 13 65 9 kök : 99 ebeveyn düğümü : 99 sol çocuk : 51 sağ çocuk :19 ebeveyn düğümü : 51 sol çocuk : 10 sağ çocuk :3 ebeveyn düğümü : 19 sol çocuk : 13 sağ çocuk :6 ebeveyn düğümü : 10 sol çocuk : 5 sağ çocuk :999999999 ebeveyn düğümü : 99 sol çocuk : 51 sağ çocuk :19 ebeveyn düğümü : 51 sol çocuk : 10 sağ çocuk :3 ebeveyn düğümü : 19 sol çocuk : 13 sağ çocuk :6 ebeveyn düğümü : 10 sol çocuk : 5 sağ çocuk :999 ebeveyn düğümü : 99 sol çocuk : 51 sağ çocuk :19 ebeveyn düğümü : 51 sol çocuk : 10 sağ çocuk :3 ebeveyn düğümü : 19 sol çocuk : 13 sağ çocuk :6 ebeveyn düğümü : 10 sol çocuk : 5 sağ çocuk :96 üst düğüm : 10 sol çocuk : 5 sağ çocuk :96 üst düğüm : 10 sol çocuk : 5 sağ çocuk :9
Bu kodda, Dizi oluşturulur ve sayılarla doldurulur. İkinci bir dizi, newArray oluşturulur ve bu sefer maxheapCreate yönteminin sonucunu , maksimum yığın dizisini içerecektir . maxHeapCreate yöntemi main'den çağrılır ve burada yeni bir dizi theNewArr oluşturulur ve maxHeapify sonuçlarıyla doldurulur. Bu, girdi dizisi boyutunun yarısından fazlasını döngüye sokarak yapılır. Döngünün her geçişi için, maxHeapify yöntemi , dizinin ortasındaki öğeden başlayıp ilkiyle biten olarak adlandırılır. Her maxHeapify çağrısı için, üst düğümün sol çocuğu ve sağ çocuğu i bulunur ve hangisinin en büyük olduğunu bulmak için kontroller yapılır ve bunu maxVal olarak tanımlar . Eğer maxVal, ana düğüme eşit değilse, o zaman bir takas yapılır, böylece ana düğüm ve maxVal yer değiştirir ve ardından bu kez maxVal üzerinde maxHeapify tekrar çağrılır ve önceki adımların aynısı yapılır. Sonunda maksimum yığın oluşturulacak ve gerçekleştirilecek başka yineleme olmayacak. Güncellenen dizi, şimdi main'e newArray olarak döndürülür ve ardından ardışık her öğe konsola yazdırılır. yeni dizişimdi bir maksimum yığın. PriorityQueue kullanan önceki örnekte olduğu gibi, sayıların yazıldığına dikkat edin: kök, kökün sağ çocuğu ebeveyn olarak, kökün sol çocuğu ebeveyn olarak, ilk sağ çocuğun sağ çocuğu ebeveyn olarak, ilkin sol çocuğu ebeveyn olarak sol-çocuk, ebeveyn olarak ilk sol-çocuğun sağ-çocuğu, ebeveyn olarak ilk sağ-çocuğun sol-çocuğu vb . Karşılaştırma ardışık öğeler arasında yapıldığından, PriorityQueue kullanıldığındakilerden biraz farklı bir sıradadırlar. oysa maxheapify örneğinde, düğüm dizideki sonraki iki ardışık öğeyle karşılaştırılır ve en büyük değerle değiştirilir. Kısaca iki farklı algoritma kullanılmaktadır. Her ikisi de bir maksimum yığın oluşturur.
GO TO FULL VERSION