Binære Søketrær Lars Vidar Magnusson 14.2.2014 Kapittel 12 Binære Søketrær Søking Insetting Sletting
Søketrær Søketrær er datastrukturer som støtter mange dynamiske sett operasjoner. Kan bli brukt både som dictionary og prioritetskø. Kjøretiden til operasjonene er proposjonal med høyden til treet. I bestefall er kjøretiden Θ(log n). I verstefall er kjøretiden Θ(n). Det finnes mange ulike søketrær. I dennne forelesningen skal vi se på binære søketrær.
Binære Søketrær Binære søketrær er en viktig datastruktur for dynamiske sett. Flere av operasjonene kan implementeres med O(h) kjøretid, hvor h er høyden til treet. Et binært tre representeres som et sett av noder som er lenket sammen med pekere (introdusert i forelesning 9). Hver node inneholder følgende felt. En nøkkel (og eventuelt satelittdata) En peker til venstre subtre En peker til høyre subtre En peker foreldernoden I et binært søketre T peker T.root til rotnoden, og T.root.p = nil.
Hva Gjør et Binært Tre til et Binært Søketre? Det som skiller et binært søketre fra et normalt binært tre er følgende egenskap. Hvis y er i venstre subtre til x, så må y.key x.key Hvis y er i høyre subtre til x, så må y.key x.key
Eksempler på et Binære Søketrær Figurene under viser to binære søketrær. a viser et noenlunde komplett binært søketre b viser et ubalansert binært søketre
Inorder-Tree-Walk Algoritmen Egenskapen til binære søketrær gjør det mulig å skrive ut elementene i sortert rekkefølge ved å utføre en såkalt inorder traversering (inorder tree walk). Hvordan Inorder-Tree-Walk fungerer Sjekk slik at nåværende node x ikke er nil. Skriv ut alle verdiene i venstre subtre rekursivt Skriv ut x Skriv ut alle verdiene i høyre subtre rekursivt
Inorder-Tree-Walk Algoritmen Pseukoden til Inorder-Tree-Walk er listet under. Intuitivt kan vi si at kjøretiden er Θ(n) siden algoritmen skriver ut alle elementene i treet en gang. Fagboka gir et detaljert bevis.
Andre Traverseringer Inorder-Tree-Walk algoritmen travererer det binære treet inorder. Dette gir mening når det er snakk om utskrifter i rekkefølge, men hvis det var snakk om andre operasjoner kan det være fordelaktig med andre traverseringer. Ved å flytte på koden som jobber på nåværende nodes element kan vi oppnå andre traverseringer. Flytter koden før det første rekursive kallet får vi preorder traversering. Flytter koden etter det siste rekursive kallet får vi postorder traversering.
Tree-Search Algoritmen Pseudokoden for Tree-Search algoritmen kan brukes for å utføre spørringer på et binært søketre. Det første kallet til algoritmen blir Tree-Search(T. root, k). Kjøretiden til algoritmen er avhengig av høyden til treet i.e. O(h). Fagboka gir også pseudokode til en iterativ utgave av algoritmen.
Tree-Minimum og Tree-Maximum Algoritmene Egenskapen til binære søketrær gjør at det er svært enkelt å hente ut største og minste verdi. Tree-Minimum og Tree-Maximum algoritmene returnerer henholdsvis det minste og største elementet i treet. Kjøretiden til begge algoritmene er O(h).
Tree-Successor og Tree-Predecessor Algoritmene Hvis vi antar at nøklene er unike, så er etterfølgeren til en node x node y slik at y.key er den minste nøkkelen større enn x.key. Vi kan finne en etterfølger (successor) utifra strukturen på treet i.e. ingen sammenligning av nøkler er nødvendig. Det er to tilfeller: Hvis node x har et høyre subtre (som ikke er nil), så er etterfølgeren minste verdi i høyre subtre. Hvis node x ikke har et høyre subtre må vi gå oppover i treet til vi finner en node som har x i venstre subtre. Forgjengeren (predecessor) operasjonen er symmetrisk med etterfølger operasjonen.
Tree-Successor og Tree-Predecessor Algoritmene Pseudokoden til Tree-Successor er listet under. Kjøretiden til algoritmen er O(h) siden vi enten går opp eller ned i treet i en enkel sti.
Tree-Insert Algoritmen Innsetting i et binært tre er nokså enkelt. Vi må bare traversere nedover i treet til vi finner korrekt plass for det nye elementet. Vi ivaretar to pekere x og y hvor x er gjeldende node som sjekkes og y er foreldernoden til x. Vi går til x.left hvis z.key < x.key og til x.left hvis z.key x.key. Vi har kommet til korrekt posisjon når x = nil. Sett inn det nye elementet z i enten y.left eller y.right.
Tree-Insert Algoritmen Pseudokoden for innsetting i et binært søketre er listet under. Kjøretiden til Tree-Insert er bundet av høyden til treet i.e. O(h).
Tree-Delete Algoritmen Det er litt mer komplisert å slette fra et binært søketre enn det er å legge til nye elementer. Konseptuelt så har vi tre tilfeller når vi skal slette element z: z har ingen barn vi kan bare fjerne den direkte z har et barn vi lar barnet erstatte plassen til z i treet z har to barn vi finner z sin etterfølger y og lar den erstatte z (dette er litt lettere sagt enn gjort). Disse tilfellene er strukturert litt annerledes i algoritmen, men ideen er den samme.
Hjelpefunksjonen Transplant Transplant hjelpefunksjonen gjør det lett å erstatte et subtre med et annet. Gjør u sin forelder til v sin forelder (hvis ikke u er rotnoden hvor v blir den nye roten) Forelderen til u får v som enten venstre eller høyre barn avhengig av hvor u var plasert v.left og v.right blir ikke oppdatert
Tree-Delete Algoritmen Tree-Delete algoritmen har fire ulike tilfeller Hvis z ikke har noe venstre barn så erstatter vi z med det høyre barnet (hvis høyre barn er nil så dekker det tilfellet med ingen barn) Hvis z har bare ett venstre barn så erstatter vi z med det venstre barnet
Tree-Delete Algoritmen Tree-Delete algoritmen har fire ulike tilfeller. Vi har allerede dekt de to tilfellene av med ingen eller et barn. La oss nå se på tilfellet hvor noden som skal fjernes har to barn. Vi finner z sin etterfølger y i høyre subtre. Hvis y sin forelder er z kan vi erstatte z med y og la y sitt høyre barn være som det er.
Tree-Delete Algoritmen Vi har nå dekket tre tilfeller. Det siste tilfellet forekommer når z har to barn, og etterfølgeren y sin forelder ikke er z. Her må vi utføre to steg. Erstatt y med y sitt høyre barn. Erstatt z med y.
Tree-Delete Algoritmen Pseudokoden til Tree-Delete er listet under. Kjøretiden til algoritmen er O(h).
Hvordan Minimere Kjøretiden Vi har sett flere ganger denne forelesningen at kjøretiden til operasjonene på binære søketrær er O(h). I verstefall er denne høyden den samme som antall elementer i treet i.e. O(n). I bestefall er høyden O(log n). I de neste forelesningene skal vi se på alternative søketrær som sørger for at treet er balansert. Fagboka presenterer også en randomisert utgave av binære søketrær som gjør at verstefall kan unngås.