Ang Binary Tree
Sa Java, mayroong maraming iba't ibang uri ng mga istruktura ng data. Ang bunton ay batay sa isang istraktura ng puno na tinatawag na isang binary tree . Binubuo ang isang binary tree ng mga node, na ang bawat isa ay maaaring magkaroon ng maximum na 2 child node: Ang isang binary tree ay binubuo ng isang parent node na maaaring magkaroon ng 0 hanggang 2 node. Maaari itong magkaroon ng left-child node at/o right-child node, o walang node. Sa isang kumpletong binary tree, ang lahat ng mga node ay pinupunan maliban sa huling antas na maaaring puno, ngunit hindi kailangang puno. Ang huling antas, ang ika-na antas, ay maaaring magkaroon ng mula 1 hanggang 2n node, kung saan ang una ay nasa n = 0 at ang ugat.Max Heap
Ang max heap (o maxheap) ay isang kumpletong binary tree . Ang mahalagang bagay tungkol dito ay DAPAT may halaga ang parent node na mas malaki kaysa o katumbas ng value ng left- and right-child node. Kung hindi ito susundin, wala kang max heap. Ang Min heap, sa kabilang banda, ay ang kabaligtaran ng ugat bilang ang pinakamaliit na halaga na may sunud-sunod na mga node na tumataas ang halaga; bawat child node ay may halagang mas malaki kaysa o katumbas ng magulang nito. Ito rin ay isang kumpletong binary tree. Ang isang halimbawa ng isang max heap ay: Ang max heap ay maaaring itayo mula sa isang array. Ang array na ito ay iisipin sa mga tuntunin ng isang puno. Para sa isang heap, kung ang ugat, (top parent node ng puno) ay naka-imbak sa posisyon (index) n, ito ay tinukoy para sa array, theArray , bilang theArray[n]. Ang left- at right-child node ay, samakatuwid, ay nasa theArray[2n+1] at theArray[2n+2] ayon sa pagkakabanggit. Para sa max heap, ang ugat ay nasa theArray[0] . Para sa antas n, ugat n = 0: angArr[n] ay ang parent node angArr[(2*n)+1] ay ang kaliwang child node angArr[(2*n)+2] ay ang kanang child nodeAng PriorityQueue Class
Maaaring ipatupad ang Heaps sa Java gamit ang PriorityQueue Class. Ginagamit ang PriorityQueues upang mahanap ang pinakamahalaga o hindi gaanong mahalagang item sa isang koleksyon. Ang klase ng PriorityQueue ay matatagpuan sa java.util.package . Ang PriorityQueues ay dapat mabuo ng mga bagay na maihahambing upang mailagay ang mga ito sa isang partikular na pagkakasunud-sunod sa pila. Ang PriorityQueue ay maaaring magkaroon ng isang comparator upang ang isang paghahambing sa pagitan ng mga bagay ay ginawa at ang queue ay nabuo ayon sa paghahambing na ito. Ang isang halimbawa ay:
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());
}
}
}
Nagbibigay ng output:
1 3 6 7 11
Sa halimbawang ito, ang default na laki ng intQueue ay 11, kaya't hindi nakasaad (karaniwan ay ang unang argumento bago ang comparator) at ang comparator ay ibinigay bilang:
(a,b) -> a - b
Gagawa ito ng paghahambing sa pagitan ng mga item sa intQueue at pag-uri-uriin ito sa mga haba ng array ng pataas na pagkakasunud-sunod.
Pagpapatupad ng PriorityQueue para Gumawa ng Max Heap
Nagde-default ang PriorityQueue Class sa min heap nang walang comparator. Ang min heap ay ang kabaligtaran ng max heap at kaya ang root ay ang pinakamaliit na value at ang sunud-sunod na child node ay mas malaki o katumbas ng root at kasunod na parental node. Para sa kadahilanang ito, para sa max heap, kinakailangang gumamit ng reverseOrder() mula sa balangkas ng Collections ng Java bilang comparator. Titiyakin nito na makakakuha tayo ng max heap at hindi isang min heap. Ang Klase na ito ay may mga kapaki-pakinabang na pamamaraan gaya ng add() , contains() , remove() , poll() , at peek() .Pamamaraan | Paglalarawan | Komplikado ng Oras |
---|---|---|
magdagdag (J) | Nagdaragdag ng elemento J sa dulo ng puno | O(LogN) |
tanggalin(J) | Alisin ang halaga J mula sa puno | O(N) |
poll() | Tinatanggal ang pinakamaraming elemento ng puno | O(LogN) |
silip() | Ibinabalik ang elemento ng ugat sa tuktok ng puno | O(1) |
naglalaman ng(J) | Nagbabalik ng true kung si J ang nasa pila, mali kung hindi | O(N) |
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);
}
}
Output:
99 Sukat ng Queue? 9 ang Queue na isinulat gamit ang for loop 99 51 19 13 10 5 6 3 9 Naglalaman ba angQueue ng 10? true theQueue na nakasulat gamit ang poll() 99 51 19 13 9 6 5 3 Sukat ng Pila? 0
Max Heapify
Ang Max Heapify algorithm ay ginagamit upang matiyak na ang isang binary tree ay isang max heap. Kung tayo ay nasa isang node, n, at ang mga child node nito, kaliwa at kanan ay mga max na tambak din mismo, kung gayon mahusay, mayroon tayong max heap. Kung hindi ito ang kaso sa buong puno, wala tayong max heap. Ang Max Heapify algorithm ay ginagamit upang pagbukud-bukurin ang puno upang ito ay sumunod sa mga prinsipyo ng maxheap. Gumagana lang ang Max Heapify sa isang node. Kung ang kinakailangan ay ang array ay isang max heap array, ang lahat ng sub tree ay dapat na i-convert sa maxheap bago ang ugat, nang paisa-isa. Dapat gamitin ang algorithm sa bawat node. Gagawin ito sa N/2 node (ang mga dahon ay susunod sa max na kinakailangan ng heap). Ang pagiging kumplikado ng oras ng heap ay O(NlogN), at para sa isang node sa taas X, ang pagiging kumplikado ng oras ay O(X). Ang sumusunod na code ay nagpapakita kung paano maxheapify ang isang puno (isang array).
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();
}
}
}
Nagbibigay ng output:
newArray:99 51 19 10 3 13 65 9 root : 99 parent node : 99 left child : 51 right child :19 parent node : 51 left child : 10 right child :3 parent node : 19 left child : 13 right child :6 parent node : 10 left child : 5 right bata :999999999 parent node : 99 left child : 51 right child :19 parent node : 51 left child : 10 right child :3 parent node : 19 left child : 13 right child :6 parent node : 10 left child : 5 right child :999 parent node : 99 left child : 51 right child :19 parent node : 51 left child : 10 right child :3 parent node : 19 left child : 13 right child :6 parent node : 10 left child : 5 right child :96 parent node : 10 kaliwang anak : 5 kanang anak :96 parent node : 10 kaliwang anak : 5 kanang anak :9
Sa code na ito, ang Array ay nilikha at puno ng mga numero. Ang pangalawang array, newArray , ay nilikha at sa pagkakataong ito ay maglalaman ito ng resulta ng pamamaraan, maxheapCreate , ang max heap array. Ang pamamaraan maxHeapCreate ay tinatawag mula sa main , at dito ang isang bagong array, theNewArr , ay nilikha at puno ng mga resulta ng maxHeapify . Ginagawa ito sa pamamagitan ng pag-loop sa kalahati ng laki ng input array. Para sa bawat pass ng loop, method maxHeapify , ay tinatawag na simula sa elemento sa gitna ng array at nagtatapos sa una. Para sa bawat tawag ng maxHeapify, ang kaliwang anak at kanang anak ng parent node, i, ay matatagpuan at ginagawa ang mga pagsusuri upang mahanap kung alin ang pinakamalaki sa tatlo, na tinutukoy iyon bilang maxVal . Kung ang maxVal ay hindi katumbas ng parent node, ang isang swap ay gagawin upang ang parent node at maxVal ay mapalitan at pagkatapos ay ang maxHeapify ay tatawagin muli sa oras na ito sa maxVal at ang parehong mga hakbang ay natupad tulad ng dati. Sa kalaunan ay malilikha ang max heap at wala nang mga pag-ulit na isasagawa. Ang na-update na array, array , ay ibinalik na ngayon sa pangunahing bilang newArray at pagkatapos ay ang bawat magkakasunod na elemento ay naka-print sa console. newArrayay isa na ngayong max heap. Tandaan, tulad ng sa nakaraang halimbawa gamit ang PriorityQueue ang mga numero ay nakasulat: ugat, kanang-anak ng ugat bilang magulang, kaliwa-anak ng ugat bilang magulang, kanang-anak ng unang kanan-anak bilang magulang, kaliwa-anak ng una kaliwa-anak bilang magulang, kanang-anak ng unang kaliwang-anak bilang magulang, kaliwang-anak ng unang kanang-anak bilang magulang, atbp. Ang mga ito ay nasa isang bahagyang naiibang pagkakasunud-sunod sa mga iyon kapag gumagamit ng PriorityQueue dahil ang paghahambing ay ginagawa sa pagitan ng magkakasunod na elemento samantalang sa halimbawa ng maxheapify, ang node ay inihambing sa susunod na dalawang sunud-sunod na elemento sa array at ipinagpalit para sa pinakamalaking halaga. Sa madaling salita, dalawang magkaibang algorithm ang ginagamit. Parehong gumagawa ng max heap.
GO TO FULL VERSION