what is heap data structure java
Овај водич објашњава шта је Јава Хеап Дата Структура и сродни концепти као што су Мин Хеап, Мак Хеап, Хеап Сорт, Стацк вс Хеап са примерима:
Гомила је посебна структура података у Јави. Хрпа је структура података заснована на стаблу и може се класификовати као комплетно бинарно стабло. Сви чворови гомиле распоређени су у одређеном редоследу.
=> Посетите овде да бисте видели серију Јава обуке за све
Шта ћете научити:
Структура података гомиле у Јави
У структури података гомиле, коријенски чвор се упоређује са својом подређеном јединицом и уређује према редоследу. Дакле, ако је а основни чвор, а б његово дете, онда је својство, тастер (а)> = тастер (б) генерисаће максималну гомилу.
Горњи однос између корена и подређеног чвора назива се „Својство гомиле“.
У зависности од редоследа чворова родитеља и детета, гомила је углавном две врсте:
# 1) Мак-Хеап :У Мак-Хеап-у кључ коренског чвора је највећи од свих кључева у гомили. Треба осигурати да исто својство вриједи за сва подстабла у хрпи рекурзивно.
Дијаграм испод приказује узорак максималне гомиле. Имајте на уму да је коренски чвор већи од његове деце.
# 2) Мин-Хеап :У случају Мин-Хеап, кључ коренског чвора је најмањи или најмањи међу свим осталим кључевима присутним у гомили. Као и у Мак хеап-у, ово својство би требало бити рекурзивно тачно у свим осталим подстаблима у хрпи.
Пример, дрвета Мин-хеап, приказано је доле. Као што видимо, основни кључ је најмањи од свих осталих кључева у гомили.
Структура података гомиле може се користити у следећим областима:
- Гомиле се углавном користе за примену приоритетних редова.
- Нарочито се мин-хеап може користити за одређивање најкраћих путања између темена на Графикону.
Као што је већ поменуто, структура података гомиле је комплетно бинарно стабло које задовољава својство гомиле за роот и децу. Ова гомила се такође назива и бинарна гомила .
Бинарна гомила
Бинарна гомила испуњава следећа својства:
- Бинарна гомила је комплетно бинарно стабло. У потпуном бинарном стаблу, сви нивои осим последњег нивоа су у потпуности попуњени. На последњем нивоу, тастери су што даље лево.
- Задовољава својство гомиле. Бинарна гомила може бити мак или мин-хеап у зависности од својства хрпе које задовољава.
Бинарна гомила је обично представљена као низ. Како је то комплетно бинарно стабло, лако се може представити као низ. Тако ће у приказу низа бинарне хрпе основни елемент бити А (0) где је А низ који се користи за представљање бинарне гомиле.
Дакле, уопште за било који итхчвор у бинарном представљању низа хрпе, А (и), можемо представити индексе осталих чворова како је приказано доле.
А ((и-1) / 2) | Представља надређени чвор |
---|---|
Приступ је бржи. | Спорије од хрпе. |
А ((2 * и) +1) | Представља леви подређени чвор |
А ((2 * и) +2) | Представља прави подређени чвор |
Размотрите следећу бинарну хрпу:
Приказ низа горње мин бинарне хрпе је како следи:
Као што је горе приказано, гомила се прелази према редослед нивоа односно елементи се прелазе слева надесно на сваком нивоу. Када се елементи на једном нивоу исцрпе, прелазимо на следећи ниво.
Даље ћемо имплементирати бинарну хрпу у Јави.
Програм у наставку приказује бинарну гомилу у Јави.
import java.util.*; class BinaryHeap { private static final int d= 2; private int() heap; private int heapSize; //BinaryHeap constructor with default size public BinaryHeap(int capacity){ heapSize = 0; heap = new int( capacity+1); Arrays.fill(heap, -1); } //is heap empty? public boolean isEmpty(){ return heapSize==0; } //is heap full? public boolean isFull(){ return heapSize == heap.length; } //return parent private int parent(int i){ return (i-1)/d; } //return kth child private int kthChild(int i,int k){ return d*i +k; } //insert new element into the heap public void insert(int x){ if(isFull()) throw new NoSuchElementException('Heap is full, No space to insert new element'); heap(heapSize++) = x; heapifyUp(heapSize-1); } //delete an element from the heap at given position public int delete(int x){ if(isEmpty()) throw new NoSuchElementException('Heap is empty, No element to delete'); int key = heap(x); heap(x) = heap(heapSize -1); heapSize--; heapifyDown(x); return key; } //maintain heap property during insertion private void heapifyUp(int i) { int temp = heap(i); while(i>0 && temp > heap(parent(i))){ heap(i) = heap(parent(i)); i = parent(i); } heap(i) = temp; } //maintain heap property during deletion private void heapifyDown(int i){ int child; int temp = heap(i); while(kthChild(i, 1) heap(rightChild)?leftChild:rightChild; } //print the heap public void printHeap() { System.out.print('nHeap = '); for (int i = 0; i Излаз:
нХеап = 7 4 6 1 3 2 5
Минимална гомила у Јави
Минимална хрпа у Јави је комплетно бинарно стабло. У мин-хеап-у, коријенски чвор је мањи од свих осталих чворова у хрпи. Генерално, кључна вредност сваког унутрашњег чвора је мања или једнака његовим подређеним чворовима.
Што се тиче представљања низа мин-хеап-а, ако је чвор ускладиштен на позицији „и“, његов леви подређени чвор је ускладиштен на положају 2и + 1, а затим је десни подређени чвор на положају 2и + 2. Положај (и-1) / 2 враћа свој надређени чвор.
У наставку су наведене разне операције које подржава мин-хеап.
# 1) Уметни (): У почетку се на крају стабла додаје нови кључ. Ако је кључ већи од надређеног чвора, својство гомиле се одржава. У супротном, треба да пређемо кључем према горе да бисмо испунили својство гомиле. Операција уметања у минималну гомилу траје О (лог н) време.
# 2) ектрацтМин (): Ова операција уклања минимални елемент из гомиле. Имајте на уму да би својство гомиле требало одржавати након уклањања основног елемента (мин елемента) из гомиле. Цела ова операција траје О (Логн).
# 3) гетМин (): гетМин () враћа корен хрпе који је уједно и минимални елемент. Ова операција се врши у О (1) времену.
Доље је дато дрво примера за Мин-хеап.

Горњи дијаграм приказује стабло мин-хеап. Видимо да је корен дрвета минимални елемент у дрвету. Како је корен на локацији 0, његово лево дете је постављено на 2 * 0 + 1 = 1, а десно дете на 2 * 0 + 2 = 2.
Минимални алгоритам хрпе
Доље је дат алгоритам за изградњу мин-хеап-а.
procedure build_minheap Array Arr: of size N => array of elements { repeat for (i = N/2 ; i >= 1 ; i--) call procedure min_heapify (A, i); } procedure min_heapify (var A( ) , var i, var N) { var left = 2*i; var right = 2*i+1; var smallest; if(left <= N and A(left) < A( i ) ) smallest = left; else smallest = i; if(right <= N and A(right) < A(smallest) ) smallest = right; if(smallest != i) { swap A( i ) and A( smallest )); call min_heapify (A, smallest,N); } }
Имплементација минималне хрпе у Јави
Мин-хеап можемо применити било помоћу низа или редова приоритета. Имплементација мин-хеап-а помоћу приоритетних редова је подразумевана имплементација јер се приоритетни ред имплементира као мин-хеап.
Следећи Јава програм имплементира мин-хеап помоћу низова. Овде користимо приказ низа за гомилу, а затим примењујемо функцију хеапифи за одржавање својства гомиле сваког елемента додатог у гомилу. На крају, приказујемо гомилу.
class Min_Heap { private int() HeapArray; private int size; private int maxsize; private static final int FRONT = 1; //constructor to initialize the HeapArray public Min_Heap(int maxsize) { this.maxsize = maxsize; this.size = 0; HeapArray = new int(this.maxsize + 1); HeapArray(0) = Integer.MIN_VALUE; } // returns parent position for the node private int parent(int pos) { return pos / 2; } // returns the position of left child private int leftChild(int pos) { return (2 * pos); } // returns the position of right child private int rightChild(int pos) { return (2 * pos) + 1; } // checks if the node is a leaf node private boolean isLeaf(int pos) { if (pos >= (size / 2) && pos HeapArray(leftChild(pos)) || HeapArray(pos) > HeapArray(rightChild(pos))) { // swap with left child and then heapify the left child if (HeapArray(leftChild(pos)) = maxsize) { return; } HeapArray(++size) = element; int current = size; while (HeapArray(current) = 1; pos--) { minHeapify(pos); } } // remove and return the heap elment public int remove() { int popped = HeapArray(FRONT); HeapArray(FRONT) = HeapArray(size--); minHeapify(FRONT); return popped; } } class Main{ public static void main(String() arg) { //construct a min heap from given data System.out.println('The Min Heap is '); Min_Heap minHeap = new Min_Heap(7); minHeap.insert(12); minHeap.insert(15); minHeap.insert(30); minHeap.insert(40); minHeap.insert(50); minHeap.insert(90); minHeap.insert(45); minHeap.minHeap(); //display the min heap contents minHeap.display(); //display root node of the min heap System.out.println('The Min val(root node):' + minHeap.remove()); } }
Излаз:

Максимална гомила у Јави
Максимална гомила је такође комплетно бинарно стабло. У максималној гомили, коријенски чвор је већи или једнак подређеним чворовима. Генерално, вредност било ког унутрашњег чвора у максималној гомили је већа или једнака његовим подређеним чворовима.
Док се максимална гомила пресликава на низ, ако је било који чвор ускладиштен на положају „и“, његово лево дете је ускладиштено на 2и +1, а десно дете на 2и + 2.
Типична Мак-хеап ће изгледати као што је приказано доле:

У горњем дијаграму видимо да је коријенски чвор највећи у гомили и да његови подређени чворови имају вредности мање од коренског чвора.
Слично мин-хеап-у, мак гомила такође може бити представљена као низ.
Дакле, ако је А низ који представља максималну гомилу, онда је А (0) коријенски чвор. Слично томе, ако је А (и) било који чвор у максималној гомили, онда су следећи остали суседни чворови који се могу представити помоћу низа.
- А ((и-1) / 2) представља надређени чвор А (и).
- А ((2и +1)) представља леви подређени чвор А (и).
- А (2и + 2) враћа десни подређени чвор А (и).
Операције које се могу изводити на Мак Хеап-у дате су у наставку.
# 1) Убаци: Операција уметања убацује нову вредност у стабло максималне гомиле. Умеће се на крај стабла. Ако је нови кључ (вредност) мањи од надређеног чвора, тада се задржава својство гомиле. У супротном, дрво треба гомилати да би се одржало својство гомиле.
шта је код сигурносног кључа
Временска сложеност операције уметања је О (лог н).
# 2) ЕктрацтМак: Операција ЕктрацтМак уклања максималан елемент (роот) из максималне гомиле. Операција такође гомила максималну гомилу ради одржавања својства гомиле. Временска сложеност ове операције је О (лог н).
# 3) гетМак: операција гетМак враћа коријенски чвор максималне гомиле са временском сложеношћу О (1).
Доле наведени Јава програм примењује максималну гомилу. Овде користимо АрраиЛист да представимо највише елемената гомиле.
import java.util.ArrayList; class Heap { void heapify(ArrayList hT, int i) { int size = hT.size(); int largest = i; int l = 2 * i + 1; int r = 2 * i + 2; if (l hT.get(largest)) largest = l; if (r hT.get(largest)) largest = r; if (largest != i) { int temp = hT.get(largest); hT.set(largest, hT.get(i)); hT.set(i, temp); heapify(hT, largest); } } void insert(ArrayList hT, int newNum) { int size = hT.size(); if (size == 0) { hT.add(newNum); } else { hT.add(newNum); for (int i = size / 2 - 1; i >= 0; i--) { heapify(hT, i); } } } void deleteNode(ArrayList hT, int num) { int size = hT.size(); int i; for (i = 0; i = 0; j--) { heapify(hT, j); } } void printArray(ArrayList array, int size) { for (Integer i : array) { System.out.print(i + ' '); } System.out.println(); } } class Main{ public static void main(String args()) { ArrayList array = new ArrayList(); int size = array.size(); Heap h = new Heap(); h.insert(array, 3); h.insert(array, 4); h.insert(array, 9); h.insert(array, 5); h.insert(array, 2); System.out.println('Max-Heap array: '); h.printArray(array, size); h.deleteNode(array, 4); System.out.println('After deleting an element: '); h.printArray(array, size); } }
Излаз:

Минимална хрпа приоритета у Јави
Структура података о реду приоритета у Јави може се директно користити за представљање мин-хеап-а. По дефаулту, приоритетни ред имплементира мин-хеап.
Програм у наставку приказује мин-хрпу у Јави користећи приоритетни ред.
import java.util.*; class Main { public static void main(String args()) { // Create priority queue object PriorityQueue pQueue_heap = new PriorityQueue(); // Add elements to the pQueue_heap using add() pQueue_heap.add(100); pQueue_heap.add(30); pQueue_heap.add(20); pQueue_heap.add(40); // Print the head (root node of min heap) using peek method System.out.println('Head (root node of min heap):' + pQueue_heap.peek()); // Print min heap represented using PriorityQueue System.out.println('
Min heap as a PriorityQueue:'); Iterator iter = pQueue_heap.iterator(); while (iter.hasNext()) System.out.print(iter.next() + ' '); // remove head (root of min heap) using poll method pQueue_heap.poll(); System.out.println('
Min heap after removing root node:'); //print the min heap again Iterator iter2 = pQueue_heap.iterator(); while (iter2.hasNext()) System.out.print(iter2.next() + ' '); } }
Излаз:

Приоритетни ред Максимална гомила у Јави
Да бисмо представили максималну гомилу у Јави користећи приоритетни ред, морамо да користимо Цоллецтионс.реверсеОрдер да обрнемо мин-хеап. Редослед приоритета директно представља мин-хрпу у Јави.
Применили смо Мак Хеап користећи приоритетни ред у доњем програму.
import java.util.*; class Main { public static void main(String args()) { // Create empty priority queue //with Collections.reverseOrder to represent max heap PriorityQueue pQueue_heap = new PriorityQueue(Collections.reverseOrder()); // Add items to the pQueue using add() pQueue_heap.add(10); pQueue_heap.add(90); pQueue_heap.add(20); pQueue_heap.add(40); // Printing all elements of max heap System.out.println('The max heap represented as PriorityQueue:'); Iterator iter = pQueue_heap.iterator(); while (iter.hasNext()) System.out.print(iter.next() + ' '); // Print the highest priority element (root of max heap) System.out.println('
Head value (root node of max heap):' + pQueue_heap.peek()); // remove head (root node of max heap) with poll method pQueue_heap.poll(); //print the max heap again System.out.println('
Max heap after removing root: '); Iterator iter2 = pQueue_heap.iterator(); while (iter2.hasNext()) System.out.print(iter2.next() + ' '); } }
Излаз:

Сортирање гомиле у Јави
Хеап сортирање је техника поређења поређења слична сортирању селекције у којој за сваку итерацију бирамо максималан елемент у низу. Хеап сорт користи структуру података Хеап и сортира елементе стварањем мин или мак гомиле из низа елемената који ће се сортирати.
Већ смо разговарали да у хрпи мин и мак коријенски чвор садржи елемент минимум и максимум низа. У сортирању хрпе, коријенски елемент хрпе (мин или мак) уклања се и премешта у сортирани низ. Преостала гомила се затим гомила да би се одржало својство гомиле.
Дакле, морамо извршити два корака рекурзивно да бисмо сортирали дати низ помоћу хеап сорт.
- Направите гомилу од датог низа.
- Неколико пута уклањајте основни елемент из гомиле и преместите га у сортирани низ. Преоптеретити преосталу гомилу.
Сложеност времена сортирања гомиле је О (н лог н) у свим случајевима. Сложеност простора је О (1).
Алгоритам сортирања гомиле у Јави
Доље су дати алгоритми сортирања гомиле за сортирање датог низа у растућем и силазном редоследу.
# 1) Алгоритам сортирања гомиле за сортирање у растућем редоследу:
- Направите максималну гомилу за сортирање датог низа.
- Избришите корен (максимална вредност у улазном низу) и преместите га у сортирани низ. Поставите последњи елемент у низ у корену.
- Ојачајте нови корен гомиле.
- Понављајте кораке 1 и 2 док се читав низ не сортира.
# 2) Алгоритам сортирања гомиле за сортирање у опадајућем редоследу:
- Конструисати мин хрпу за дати низ.
- Уклоните корен (минимална вредност у пољу) и замените га последњим елементом у низу.
- Ојачајте нови корен гомиле.
- Понављајте кораке 1 и 2 док се читав низ не сортира.
Имплементација сортирања гомиле у Јави
Испод наведени Јава програм користи сортирање гомиле за сортирање низа у растућем редоследу. За ово прво конструишемо максималну хрпу, а затим рекурзивно заменимо и гомиламо коријенски елемент како је наведено у горњем алгоритму.
import java.util.*; class HeapSort{ public void heap_sort(int heap_Array()) { int heap_len = heap_Array.length; // construct max heap for (int i = heap_len / 2 - 1; i >= 0; i--) { heapify(heap_Array, heap_len, i); } // Heap sort for (int i = heap_len - 1; i >= 0; i--) { int temp = heap_Array(0); heap_Array(0) = heap_Array(i); heap_Array(i) = temp; // Heapify root element heapify(heap_Array, i, 0); } } void heapify(int heap_Array(), int n, int i) { // find largest value int largest = i; int left = 2 * i + 1; int right = 2 * i + 2; if (left heap_Array(largest)) largest = left; if (right heap_Array(largest)) largest = right; // recursively heapify and swap if root is not the largest if (largest != i) { int swap = heap_Array(i); heap_Array(i) = heap_Array(largest); heap_Array(largest) = swap; heapify(heap_Array, n, largest); } } } class Main{ public static void main(String args()) { //define input array and print it int heap_Array() = {6,2,9,4,10,15,1,13}; System.out.println('Input Array:' + Arrays.toString(heap_Array)); //call HeapSort method for given array HeapSort hs = new HeapSort(); hs.heap_sort(heap_Array); //print the sorted array System.out.println('Sorted Array:' + Arrays.toString(heap_Array)); } }
Излаз:

Укупна временска сложеност технике сортирања гомиле је О (нлогн). Временска сложеност технике Хеапифи је О (логн). Док је временска сложеност изградње гомиле О (н).
Стацк вс Хеап Ин Јава
Хајде сада да табуларизујемо неке разлике између структуре података стека и гомиле.
Гомила Гомила Склоп је линеарна структура података. Гомила је хијерархијска структура података. Прати ЛИФО (Ласт Ин, Фирст Оут) наручивање. Прелазак је у равномерном редоследу. Углавном се користи за статичку алокацију меморије. Користи се за динамичку алокацију меморије. Меморија се додељује суседно. Меморија се распоређује на случајним локацијама. Величина стека је ограничена у складу са оперативним системом. Нема ограничења величине гомиле која намеће оперативни систем. Стек има приступ само локалним променљивим. Хеап има додељене глобалне променљиве. Додјела / ослобађање меморије је аутоматско. Додељивање / ослобађање треба да изврши ручно програмер. Стек се може имплементирати помоћу низова, повезане листе, АрраиЛист, итд. Или било које друге линеарне структуре података. Гомила се имплементира помоћу низова или дрвећа. Трошкови одржавања ако су мањи. Скупље за одржавање. Може резултирати недостатком меморије јер је меморија ограничена. Нема мањка меморије, али може патити од фрагментације меморије.
Често постављана питања
П # 1) Да ли је стек бржи од Хеап-а?
Одговор: Стек је бржи од гомиле, јер је приступ у стеку линеаран у односу на гомилу.
П # 2) За шта се користи гомила?
Одговор: Гомила се углавном користи у алгоритмима који проналазе минимални или најкраћи пут између две тачке попут Дијкстриног алгоритма, за сортирање помоћу сортирања хрпе, за имплементације реда приоритета (мин-хеап) итд.
П # 3) Шта је гомила? Које су његове врсте?
Одговор: Гомила је хијерархијска структура података заснована на стаблу. Хрпа је комплетно бинарно стабло. Гомиле су две врсте, тј. Максимална гомила у којој је коријенски чвор највећи међу свим чворовима; Минимална гомила у којој је коријенски чвор најмањи или најмањи међу свим кључевима.
П # 4) Које су предности Хеап-а над стеком?
Одговор: Главна предност гомиле над стеком је у гомили, меморија се динамички распоређује и стога нема ограничења колико меморије се може користити. Друго, на стеку се могу доделити само локалне променљиве, док такође можемо доделити глобалне променљиве на хрпи.
П # 5) Може ли Хеап имати дупликате?
Одговор: Да, нема ограничења да се чворови са дупликатима кључева налазе у гомили, јер је гомила комплетно бинарно стабло и не задовољава својства бинарног стабла претраживања.
Закључак
У овом упутству смо разговарали о врстама гомиле и сортирању гомиле помоћу типова гомиле. Такође смо видели детаљну примену његових типова у Јави.
=> Овде погледајте савршен водич за обуку за Јава.
Препоручено читање
- Водич за Јава графикон - Како применити структуру података графикона
- Увод у структуре података на језику Ц ++
- Сортирање гомиле у Ц ++ са примерима
- Структура података АВЛ стабла и гомиле у Ц ++
- Структура података бинарног стабла у језику Ц ++
- Структура података у реду у Ц ++ са илустрацијом
- Структура података кружно повезане листе на Ц ++ са илустрацијом
- Основе Јава-а: Јава синтакса, Јава Цласс и основни Јава концепти