What is heap data structure?

Heap Datastruktur: En Komplet Guide

21/04/2014

Rating: 4.84 (5809 votes)

I en verden af datalogi og programmering er effektivitet altafgørende. At kunne organisere og tilgå data hurtigt kan være forskellen på et langsomt og et lynhurtigt program. En af de mest fundamentale og effektive datastrukturer, som enhver udvikler bør kende til, er heap'en. En heap er ikke bare en tilfældig samling af data; det er en specialiseret træ-baseret datastruktur, der udmærker sig ved hurtigt at kunne finde det største eller mindste element. Dette gør den ideel til en række applikationer, herunder implementering af prioritetskøer og den berømte Heapsort-algoritme. I denne artikel vil vi udforske, hvad en heap er, de forskellige typer, de operationer, man kan udføre på den, og hvor den anvendes i praksis.

What operations can be performed on a heap data structure?
The following operations can be performed on a heap data structure: A new element is always inserted at the last child of the original heap. The new element may now violate the heap property that a heap must satisfy. Therefore, an operation known as reheapify upward is performed on the heap.
Indholdsfortegnelse

Hvad er en Heap Datastruktur?

En heap er i sin essens et komplet binært træ, der opfylder en bestemt betingelse, kendt som "heap-egenskaben". Et komplet binært træ er et træ, hvor alle niveauer er fuldstændigt udfyldt, undtagen muligvis det sidste niveau, som udfyldes fra venstre mod højre. Denne struktur gør det muligt at repræsentere en heap meget effektivt i hukommelsen ved hjælp af et simpelt array, hvilket eliminerer behovet for pointere til at forbinde noder.

Heap-egenskaben definerer forholdet mellem en forældernode og dens børnenoder. Der findes to primære typer heaps, som hver især har deres egen version af denne egenskab:

  • Max-Heap: I en max-heap er værdien (eller nøglen) i en forældernode altid større end eller lig med værdierne i dens børnenoder. Dette betyder, at det absolut største element i hele heap'en altid vil befinde sig i roden (den øverste node).
  • Min-Heap: I en min-heap er det omvendt. Værdien i en forældernode er altid mindre end eller lig med værdierne i dens børnenoder. Her vil det absolut mindste element altid være at finde i roden.

Det er vigtigt at bemærke, at en heap kun er delvist ordnet. Der er ingen specifik ordensrelation mellem søskendenoder eller fætter/kusine-noder. Den eneste regel er den vertikale relation mellem forælder og barn. Dette adskiller en heap fra f.eks. et binært søgetræ, hvor alle noder til venstre for en forælder er mindre, og alle til højre er større.

Kerneoperationer på en Heap

For at kunne bruge en heap effektivt, er der en række centrale operationer, vi skal mestre. Disse operationer sikrer, at heap-egenskaben opretholdes, selv når vi tilføjer eller fjerner elementer.

Indsættelse (Insertion)

Når et nyt element skal tilføjes til en heap, følger processen en simpel, men stringent procedure for at bevare strukturen:

  1. Tilføj elementet: Det nye element indsættes altid på den første ledige plads i træets nederste niveau, hvilket svarer til at tilføje det til slutningen af arrayet, der repræsenterer heap'en.
  2. Genopret heap-egenskaben (Heapify Up): Efter indsættelsen kan det nye element krænke heap-egenskaben. For at rette op på dette udføres en proces, der ofte kaldes `heapify-up` eller `bubble-up`. Elementet sammenlignes med sin forælder. Hvis det nye element er større end sin forælder (i en max-heap) eller mindre (i en min-heap), bytter de plads. Denne proces gentages rekursivt opad i træet, indtil elementet er på sin korrekte plads, enten fordi det ikke længere krænker egenskaben, eller fordi det er nået til roden.

Lad os tage et eksempel med en max-heap: [100, 19, 36, 17]. Hvis vi vil indsætte 25, tilføjes det til sidst: [100, 19, 36, 17, 25]. Nu sammenlignes 25 med sin forælder (19). Da 25 > 19, bytter de plads: [100, 25, 36, 17, 19]. Processen stopper, da 25's nye forælder (100) er større.

Sletning (Deletion)

Den mest almindelige sletningsoperation i en heap er at fjerne rodelementet, da det er her, det maksimale (eller minimale) element befinder sig. Dette er kernen i, hvordan en prioritetskø fungerer. Processen er som følger:

  1. Erstat roden: Rodelementet fjernes, men for at undgå et "hul" i træet, tages det allersidste element i heap'en og placeres i rodens position.
  2. Fjern det sidste element: Det oprindelige sidste element er nu fjernet fra sin plads, hvilket forkorter arrayet med én.
  3. Genopret heap-egenskaben (Heapify Down): Den nye rod vil sandsynligvis krænke heap-egenskaben. For at løse dette udføres en `heapify-down` eller `sift-down` proces. Den nye rod sammenlignes med sine børn. I en max-heap bytter den plads med det største af sine børn. Denne proces fortsætter rekursivt nedad i træet, indtil noden er på sin korrekte plads, hvor den er større end begge sine børn, eller den er blevet en løvnode (en node uden børn).

Find Maksimum / Find Minimum

Dette er den simpleste og hurtigste operation på en heap. Takket være heap-egenskaben er det garanteret, at det største element (i en max-heap) eller det mindste element (i en min-heap) altid er placeret i roden af træet. At finde dette element kræver derfor blot, at man kigger på det første element i arrayet. Denne operation har en tidskompleksitet på O(1), hvilket betyder, at den tager konstant tid, uanset hvor stor heap'en er.

What is a heap in Java?
A Heap is a complete binary tree data structure that satisfies the heap property: for every node, the value of its children is greater than or equal to its own value. Heaps are usually used to implement priority queues, where the smallest (or largest) element is always at the root of the tree. Check if an array is Heap?

Sammenligning af Heap-typer

For at give et klart overblik er her en tabel, der sammenligner de to primære heap-typer.

EgenskabMax-HeapMin-Heap
Heap-egenskabForældrenode ≥ BørnenodeForældrenode ≤ Børnenode
Rodens værdiDet største element i heap'enDet mindste element i heap'en
Primær anvendelseFind hurtigt det maksimale element (f.eks. i Heapsort, faldende orden)Find hurtigt det minimale element (f.eks. prioritetskøer, Dijkstra's algoritme)

Praktiske Anvendelser af Heaps

Heaps er ikke bare en teoretisk konstruktion; de er en arbejdshest inden for mange områder af datalogi.

  • Heapsort: Dette er en af de mest kendte sorteringsalgoritmer. Den fungerer ved først at bygge en max-heap ud af et usorteret array. Derefter bytter den gentagne gange rodelementet (det største) med det sidste element, fjerner det fra heap'en og kører `heapify-down` på roden. Resultatet er et sorteret array. Heapsort er en in-place algoritme med en garanteret worst-case tidskompleksitet på O(n log n).
  • Prioritetskøer: Måske den mest naturlige anvendelse af en heap. En prioritetskø er en abstrakt datastruktur, hvor hvert element har en prioritet. Når man henter et element, får man altid det med den højeste (eller laveste) prioritet. En heap er en perfekt implementering af dette, da det højest prioriterede element altid er i roden og kan tilgås i O(1) tid, mens indsættelse og fjernelse sker i O(log n) tid.
  • Grafalgoritmer: Algoritmer som Dijkstra's (til at finde den korteste vej i en graf) og Prim's (til at finde et minimalt udspændende træ) bruger ofte en min-heap til effektivt at holde styr på, hvilken node der skal besøges næste gang.
  • Selektionsalgoritmer: En heap kan bruges til effektivt at finde det k'te mindste (eller største) element i en samling af data på en mere effektiv måde end ved først at sortere hele samlingen.

Ofte Stillede Spørgsmål (FAQ)

Er en heap en sorteret datastruktur?

Nej, en heap er kun delvist ordnet. Den opretholder heap-egenskaben mellem forældre og børn, men der er ingen garanteret orden mellem søskende. For eksempel, i en max-heap, ved du, at roden er det største element, men du ved ikke, om dens venstre barn er større eller mindre end dens højre barn. For at få en fuldt sorteret liste ud af en heap, skal man bruge en algoritme som Heapsort.

Hvad er forskellen på en heap og et binært søgetræ?

Selvom begge er træ-baserede datastrukturer, har de forskellige regler og formål. I et binært søgetræ (BST) gælder det, at for enhver node er alle værdier i dens venstre undertræ mindre, og alle værdier i dens højre undertræ er større. Dette gør det meget hurtigt at søge efter en specifik værdi. I en heap er reglen, at en forælder enten er større end (max-heap) eller mindre end (min-heap) sine børn. Dette gør det hurtigt at finde det maksimale/minimale element, men langsomt at finde en specifik værdi.

Hvordan implementeres en heap typisk i hukommelsen?

En af de store fordele ved en heap (specifikt en binær heap) er, at den kan implementeres meget simpelt ved hjælp af et array eller en liste, uden behov for komplekse nodestrukturer med pointere. For en node på indeks `i` i arrayet, kan dens børn og forælder findes med simpel matematik:

  • Forælder til node `i`: `(i-1) / 2`
  • Venstre barn til node `i`: `2*i + 1`
  • Højre barn til node `i`: `2*i + 2`

Denne implicitte struktur er både plads- og tidseffektiv.

Hvis du vil læse andre artikler, der ligner Heap Datastruktur: En Komplet Guide, kan du besøge kategorien Teknologi.

Go up