Syet binært træ

Et sammensyet binært træ  er en variant af et binært træ , der tillader hurtig gennemløb - givet en pointer til en node i et sammensyet træ, kan man nemt finde den næste (og/eller forrige) node i rækkefølge .

Baggrund

Binære træer, inklusive (men ikke begrænset til) binære søgetræer og deres varianter, kan bruges til at gemme flere elementer i en bestemt rækkefølge. For eksempel antager et binært søgetræ, at dataelementer er ordnet på en eller anden måde og bevarer denne rækkefølge, når de indsættes og fjernes. En nyttig operation på et sådant træ er traversal , det vil sige at besøge elementerne i træet i den rækkefølge, de vil blive husket i (hvilket svarer til rækkefølgen af ​​noderne i tilfælde af et binært søgetræ).

Den simple rekursive traversalalgoritme, der besøger hver knude i det binære søgetræ, er som følger. Antag , at t  er en pointer til en knude eller nul . "Besøg" t kan betyde enhver operation med denne node t eller det indhold, der er tildelt den.

Traversal algoritme( t ):

Problemet med denne algoritme er, at algoritmen på grund af rekursion bruger stakplads proportionalt med højden af ​​træet. Hvis træet er dårligt afbalanceret, når denne værdi O (log n ) for et træ med n elementer. I værste fald, når træet har form af en kæde , er højden af ​​træet n , så algoritmen vil kræve O ( n ) stakplads .

I 1968 spurgte Donald Knuth , om der var en ikke-rekursiv centreret traversalalgoritme, der ikke brugte stakken og efterlod træet uændret. En løsning på dette problem er træsyning, introduceret af James H. Morris i 1979 [1] [2] .

Definition

Et syet træ er defineret som følger:

"Et binært træ sammenføjes ved at tildele alle højre underordnede pointere, som normalt ville være nul-pegere, til pointere til knudepunktets næste knude ( hvis nogen), og alle venstre underordnede pegere, som normalt ville være nul-pegere, til pointere til tidligere knudepunkter i bestilling” [3] .

Det er også muligt at finde forælderen til en node fra et sammensat binært træ uden eksplicit at bruge en markør til forælderen eller stakken, selvom det er langsommere. Dette er nyttigt, når stakken er begrænset, eller når en stak af overordnede pointere ikke er tilgængelig (til at finde en overordnet pointer ved hjælp af dybde -først-søgning ).

For at se, hvordan dette er muligt, skal du overveje en node k , der har et ret underordnet r . Så skal nodens venstre pointer r enten være et underordnet eller en pointer tilbage til k . I det tilfælde, hvor r har et venstre barn, så skal det venstre barn have sit eget venstre barn, eller en pointer tilbage til k , og så videre for alle efterfølgende venstre børn. Når vi således går gennem kæden af ​​venstre visere fra r den ene efter den anden , finder vi til sidst stingmarkøren tilbage til k . Situationen er symmetrisk, når q er det venstre underordnede af p , i hvilket tilfælde vi kan spore de højre underordnede af knudepunktet q for at få en firmwarepointer til p .

Typer af syede binære træer

  1. Enkelt blink: hver knude blinker med en pegepind enten til den forrige knude i rækkefølge eller til den næste knude i rækkefølge (venstre eller højre).
  2. Dobbeltsyning: Hver knude er syet med en pegepind til både den forrige knude og den næste (venstre og højre).

Python sprog :

def parent ( node ): hvis node er node . træ . root : return Ingen andre : x = node y = node mens Sand : hvis er_tråd ( y ): p = y . højre hvis p er Ingen eller p . venstre er ikke node : p = x mens det ikke er_tråd ( s . venstre ): p = p . venstre p = p . venstre retur p elif is_thread ( x ): p = x . venstre hvis p er Ingen eller p . højre er ikke node : p = y mens det ikke er_tråd ( s . højre ): p = p . højre p = p . højre retur p x = x . venstre y = y . ret

Centreret traversal array

Firmware er links til de forrige og næste noder i en given node i henhold til en centreret gennemgang.

Hvis den syede trærækkefølge er ABCDEFGHI, kommer D-knuden før E, og F følger E-knuden.

Eksempel

Lad os prøve at danne et syet træ ud fra et almindeligt binært træ

Den centrerede traversale vertex-rækkefølge for træet ovenfor er DBAE C. Så det tilsvarende sammensyede binære træ ville se sådan ud

Null pointer

I et m-syet binært træ med n noder er der n*m - (n-1) nul-links.

Ikke-rekursiv centreret traversal for et sammensyet binært træ

Som en ikke-rekursiv gennemløbsmetode skal metoden være en iterativ procedure, alle knudegennemløbstrin skal være i en loop, så det samme kan anvendes på alle træknuder. Vi antager igen en centreret trægennemgang. Derefter krydser vi det venstre undertræ for enhver knude først (hvis det eksisterer, og hvis vi ikke har krydset det før). Vi besøger derefter (det vil sige udskriver værdien af ​​noderne i vores tilfælde) selve noden og krydser først derefter det rigtige undertræ (hvis det findes). Hvis der ikke er noget højre træ, skal du kontrollere det syede led og gøre det syede toppunkt til den aktuelle node i betragtning. Se eksempel nedenfor.

Algoritme

Trin-1: For den aktuelle node skal du kontrollere, om der er et venstre barn, der ikke er på listen over besøgte. Hvis der er en, gå til trin 2, ellers gå til trin 3.

Trin-2: Sæt det venstre barn på listen over besøgte noder og gør det til den aktuelle node. Lad os gå videre til trin 6.

Trin-3: Udskriv noden, og hvis noden har et rigtigt barn, gå til trin 4, ellers gå til trin 5.

Trin-4: Gør det rigtige barn til den aktuelle node.

Trin-5: Hvis der findes en firmwarenode, skal du gøre den til den aktuelle node.

Trin-6: Hvis alle noder er udskrevet, skal du afslutte, ellers gå til trin 1.

Liste
trin 1 A har et venstre barn, dvs. B , som endnu ikke er besøgt, så vi sætter B i vores "liste over besøgte noder", og B bliver den aktuelle node. B
trin-2 B har også et venstre barn D , som ikke er på listen over besøgte noder. Vi sætter D i besøgslisten og gør den aktuel. BD
trin-3 Node D har ikke et venstre barn, så vi udskriver D , så tjekker vi det højre barn. D har ikke det rigtige barn, så vi kigger på det linkede link. Node har firmware til node B , så gør B aktuel. BD D
trin-4 B har et efterladt barn, men det er allerede blevet besøgt. Så vi udskriver B , og kontrollerer derefter for et rigtigt barn, men der er ikke et, så vi gør den syede knude (dvs. A ) til den nuværende. BD D.B.
trin-5 A har et venstre barn B , men det er allerede besøgt, så vi udskriver A og tjekker efter et højre barn. Node A har et ret underordnet C , og det er ikke på listen over besøgte noder, så vi tilføjer det til denne liste og gør det aktuelt. bdc DBA
trin-6 C har node E som venstre underordnet, og denne node er endnu ikke blevet besøgt, så føj node E til listen og gør den aktuel. B D C E D B A
trin-7 langt om længe….. D B A E C

Noter

  1. Morris, 1979 .
  2. Mateti, Manghirmalani, 1988 , s. 29-43.
  3. Van Wyk, 1988 , s. 175.

Litteratur

Links