Tilbake
3.2

3.2 Binære søketrær

`Tree-Insert`, `Inorder-Tree-Walk`, `Tree-Search`/`Minimum`/`Maximum` — inkludert nøkkelinnsikten at inorder på et BST gir **sortert** rekkefølge.

50 min
6 oppgaver
Binære søketrær
Din fremgang i kapitlet
0 / 6 oppgaver
Kapitlets plass i kurset

Forkunnskaper

- kap. 3.1 — hauger. Dette sto der: en maks-haug
krever at hver forelder er \ge begge barna, og den sier ingenting om
venstre mot høyre. Haugen ligger i et array A[1..n] med forelder
i/2\lfloor i/2\rfloor og barn 2i2i og 2i+12i+1. Build-Max-Heap er Θ(n)\Theta(n),
og Heapsort er Θ(nlgn)\Theta(n\lg n). Søketreet i dette kapitlet ordner i den
andre retningen, og kontrasten er halve poenget med Del 3.
- kap. 2.1 — sortering. Vi bruker at et sortert
materiale kan søkes ved halvering, og sammenligner søketreets O(h)O(h) med
sorteringens Θ(nlgn)\Theta(n\lg n).
- kap. 1.1 — de asymptotiske symbolene. Skillet mellom
OO og Θ\Theta er bevisst brukt i hele kapitlet: operasjonene er O(h)O(h),
ikke Θ(h)\Theta(h), fordi de kan stoppe tidlig.

Er logaritmen fersk: Potenser og logaritmer. I hele denne boka
betyr lgn\lg n det samme som log2n\log_2 n.

Notasjons- og pseudokodeliste

Søketreegenskapen, og kontrasten mot haugen (~11 min)

Et bibliotek har et kortregister der hvert kort peker videre til to andre kort:
ett for «lavere nummer» og ett for «høyere nummer». Leter du etter et bestemt
nummer, sammenligner du med kortet du står på og går én vei. Du slipper å lete
gjennom resten.

Det er et binært søketre. Strukturen er den samme som haugen — noder med to
barn hver — men regelen som ordner nodene er en helt annen.

Søketreegenskapen

I et binært søketre gjelder for hver node x: alle nøkler i venstre deltre
er \le x.key, og alle nøkler i høyre deltre er \ge x.key.

Regelen gjelder i hver eneste node, ikke bare i rota. Det holder ikke at
venstre barn er mindre enn x — hele venstre deltre må være det, også
barnebarna.

Det er venstre–høyre-ordenen som er poenget. Ingenting sies om hvor dypt
noe ligger, og treet trenger ikke være balansert.

Kontrasten: haugegenskapen

I en maks-haug gjelder for hver node at forelderen er \ge begge
barna. Det er en opp–ned-ordning.

En maks-haug sier ingenting om venstre mot høyre: venstre barn kan godt være
større enn høyre barn, og arrayet er ikke sortert.

Dette er felle #2 — å blande de to strukturene. Kontrollen er å spørre hva
regelen ordner: haugen ordner nedover, søketreet ordner sidelengs.

Høyden hh
Høyden til et tre er antall kanter på den lengste stien fra rota ned til et
blad. Et tre med bare rota har høyde 0.

Alle søketreoperasjonene utenom traverseringene er O(h)O(h) — de følger én sti
nedover.

Høyden er ikke bestemt av nn alene. Den ligger mellom
lgn\lfloor\lg n\rfloor (perfekt balansert) og n1n-1 (en lenket liste), og hvilken
det blir, avhenger av innsettingsrekkefølgen.

📝Oppgave 1

(Innstegsoppgave, sjanger D — definisjon med egne ord, altså én presis setning
med hovedpoenget først.)

Definér søketreegenskapen, og si med én setning hva som skiller den fra
haugegenskapen.

Tree-Insert og innsettingsveien (~12 min)

Innsetting er den enkleste operasjonen, og den som oftest håndkjøres. Ideen er
at den nye nøkkelen skal ende opp nøyaktig der et søk etter den ville stoppet.

📜Pseudokode-kontrakt: `Tree-Insert`
Antagelser om representasjon. Hver node x har feltene x.key, x.left,
x.right og x.p. Manglende barn og manglende forelder er NIL. Treet T
har T.root. Noden z som settes inn, har z.left = z.right = NIL.

Prebetingelse: T oppfyller søketreegenskapen.
Postbetingelse: T inneholder z i tillegg til de gamle nøklene, og
oppfyller fortsatt søketreegenskapen. z er et blad.

Tree-Insert(T, z)
  Input:  soeketreet T og en ny node z med noekkel z.key
  Output: T med z satt inn som blad
  y = NIL
  x = T.root
  while x != NIL
      y = x
      if z.key < x.key
          x = x.left
      else
          x = x.right
  z.p = y
  if y == NIL
      T.root = z
  else if z.key < y.key
      y.left = z
  else
      y.right = z
  Kjoeretid: O(h)

Invarianten i én setning: hvis z.key skal inn i treet, ligger den
riktige plassen i deltreet med rot x — og y er alltid forelderen til x.

Legg merke til at ingen eksisterende node flyttes. Innsettingen henger bare
på et nytt blad. Det er derfor et søketre bygget ved gjentatte innsettinger kan
bli skjevt: strukturen bestemmes helt av rekkefølgen nøklene kommer i.

Kjøretid: O(h)O(h) — løkka følger én sti fra rota og nedover, og gjør
konstant arbeid per nivå. Grensen er OO og ikke Θ\Theta fordi stien kan være
kort.

✏️Eksempel 1: Åtte innsettinger, og veien hver nøkkel tar

Åtte medlemsnumre registreres i denne rekkefølgen: `46, 25, 68, 13, 31, 57,
79, og til slutt 29`.

Sett dem inn i et tomt binært søketre med Tree-Insert, og oppgi
Inorder-Tree-Walk-utskriften til slutt.

NøkkelSammenligninger på veien nedHavner som
46rot
2525<4625 < 46, gå venstrevenstre barn av 46
6868>4668 > 46, gå høyrehøyre barn av 46
1313<4613 < 46, gå venstre; 13<2513 < 25, gå venstrevenstre barn av 25
3131<4631 < 46, gå venstre; 31>2531 > 25, gå høyrehøyre barn av 25
5757>4657 > 46, gå høyre; 57<6857 < 68, gå venstrevenstre barn av 68
7979>4679 > 46, gå høyre; 79>6879 > 68, gå høyrehøyre barn av 68
2929<4629 < 46, gå venstre; 29>2529 > 25, gå høyre; 29<3129 < 31, gå venstrevenstre barn av 31

Treet ser slik ut etterpå:
                  46
          25              68
      13      31      57      79
            29
Sluttilstanden — det du ville levert på eksamen:
13, 25, 29, 31, 46, 57, 68, 79
Kontrollen er gratis. Inorder-utskriften skal være sortert. Er den ikke
det, har du satt inn feil et sted — og du finner feilen ved å gå tilbake til
den første nøkkelen som kommer ut av rekkefølge.
Legg merke til veien 29 tok. Den gikk til venstre fra 46, til høyre fra 25,
og til venstre fra 31. Tre sammenligninger, og så et ledig sted. Det er alltid

slik: nøkkelen ender der søket etter den ville stoppet.

Høyden til treet er 3 — den lengste stien er

46–25–31–29.

📝Oppgave 2
Eksamensnivå, sjanger C

Sett inn nøklene 40, 62, 18, 55, 71, 9, 27 i denne rekkefølgen i et tomt
binært søketre.

a) Oppgi Inorder-Tree-Walk-utskriften.
b) Hva er rotas nøkkel, og hva er treets høyde?

Inorder-Tree-Walk og de tre traverseringene (~11 min)

Traverseringen er der søketreets viktigste egenskap kommer til syne.

📜Pseudokode-kontrakt: `Inorder-Tree-Walk`
Antagelser om representasjon. Som over: x.key, x.left, x.right, med
NIL for manglende barn. Kallet utenfra er
Inorder-Tree-Walk(T.root).

Prebetingelse: deltreet med rot x oppfyller søketreegenskapen.
Postbetingelse: alle nøkler i deltreet er skrevet ut, i stigende
rekkefølge.

Inorder-Tree-Walk(x)
  Input:  rota x i et deltre
  Output: alle noekler i deltreet, skrevet ut sortert
  if x != NIL
      Inorder-Tree-Walk(x.left)
      skriv ut x.key
      Inorder-Tree-Walk(x.right)
  Kjoeretid: Theta(n)

Grunnideen i én setning: søketreegenskapen sier at alt i venstre deltre er
\le x.key og alt i høyre deltre er \ge x.key — så skriver du ut venstre
først, deretter x selv, deretter høyre, kommer nøklene ut i orden.

Kjøretid: Θ(n)\Theta(n). Hver node besøkes nøyaktig én gang, og arbeidet per
node er konstant. Her er grensen tett: ingen input gjør traverseringen
kortere, siden alle nodene skal skrives ut.

De to søsknene følger samme mønster, men med utskriften plassert et annet
sted: preorder skriver x før deltrærne, og postorder skriver x
etter dem. Ingen av dem gir sortert utskrift.

✏️Eksempel 2: De tre traverseringene på samme tre

Bruk treet fra Eksempel 1 — det med rota 46 og nøklene `13, 25, 29, 31, 46,
57, 68, 79`.

Oppgi utskriften fra Inorder-Tree-Walk, fra preorder og fra postorder, og si
hva hver av dem er nyttig til.

TraverseringUtskrift
inorder (venstre, node, høyre)13, 25, 29, 31, 46, 57, 68, 79
preorder (node, venstre, høyre)46, 25, 13, 31, 29, 68, 57, 79
postorder (venstre, høyre, node)13, 29, 31, 25, 57, 79, 68, 46

Inorder gir sortert rekkefølge. Det er den ene av de tre som utnytter
søketreegenskapen, og den eneste som er interessant på eksamen.
Preorder starter i rota og tar venstre deltre ferdig før høyre. Den er
nyttig til å skrive ned et tre slik at det kan bygges opp igjen med nøyaktig

samme form — legg merke til at preorder-listen begynner med 46, som er rota.
Postorder besøker begge barna før noden selv. Den passer når noe skal

gjøres nedenfra og opp, for eksempel å frigjøre minne.
Fellen: inorder gir ikke innsettingsrekkefølgen. Innsettingsrekkefølgen
i Eksempel 1 var 46, 25, 68, 13, 31, 57, 79, 29, og den ser du ikke igjen i

noen av de tre listene. Preorder er nærmest, men er ikke den samme: den ville
gitt 46, 25, 13, 31, 29, 68, 57, 79.

📝Oppgave 3
Eksamensnivå, sjanger F

Ta stilling til hver av påstandene:

a) Inorder-Tree-Walk skriver ut nøklene i den rekkefølgen de ble satt
inn.
b) To ulike søketrær over de samme nøklene gir samme inorder-utskrift.
c) Inorder-Tree-Walk er O(h)O(h).

Søk, minimum og maksimum (~8 min)

De tre siste operasjonene er varianter av det samme: følg én sti nedover.

📜Pseudokode-kontrakt: `Tree-Search`, `Tree-Minimum` og `Tree-Maximum`
Antagelser om representasjon. Som over. Alle tre kalles med rota i det
deltreet det skal letes i.

Prebetingelse: deltreet oppfyller søketreegenskapen; for Tree-Minimum og
Tree-Maximum må det være ikke-tomt.
Postbetingelse: Tree-Search returnerer noden med nøkkelen v hvis den
finnes, ellers NIL. Tree-Minimum returnerer noden med den minste nøkkelen,
Tree-Maximum den med den største.

Tree-Search(x, v)
  Input:  rota x i et deltre og en noekkel v
  Output: noden med noekkel v, eller NIL
  while x != NIL and v != x.key
      if v < x.key
          x = x.left
      else
          x = x.right
  return x

Tree-Minimum(x)
  while x.left != NIL
      x = x.left
  return x

Tree-Maximum(x)
  while x.right != NIL
      x = x.right
  return x
  Kjoeretid: O(h) for alle tre

Grunnideen i én setning: søketreegenskapen gjør at hver sammenligning
utelukker et helt deltre — og at det minste elementet ligger så langt til
venstre som det er mulig å komme.

Kjøretid: O(h)O(h) for alle tre. Hver runde går ett nivå ned, og det finnes
hh nivåer.

Kontrasten mot maks-haugen er verdt å merke seg. I en maks-haug ligger
maksimum alltid på A[1] og koster Θ(1)\Theta(1) å finne, mens minimum
krever at du leter gjennom alle bladene, altså Θ(n)\Theta(n). I et søketre
koster begge O(h)O(h) — strukturen er mer symmetrisk.

📝Oppgave 4
Eksamensnivå, sjanger C…

Bruk treet fra Eksempel 1 (rota 46, nøklene 13, 25, 29, 31, 46, 57, 68, 79).

a) Hvilke noder besøker Tree-Search når den leter etter 57?
b) Hva returnerer Tree-Minimum(T.root) og Tree-Maximum(T.root)?
c) Hva er kjøretiden til et søk, uttrykt i høyden?

Høyden — der kjøretiden avgjøres (~8 min)

Alle kjøretidene over er O(h)O(h). Det er et ærlig svar, men det utsetter
spørsmålet: hvor stor er hh?

Svaret avhenger fullstendig av rekkefølgen nøklene ble satt inn i, og det er
her et søketre kan gå fullstendig galt.

Høydens ytterpunkter

For et binært søketre med nn noder gjelder
lgnhn1\lfloor\lg n\rfloor \le h \le n-1.

Nedre grense nås av et perfekt balansert tre; øvre grense nås når nøklene
settes inn i stigende eller synkende rekkefølge, slik at hver
innsetting går samme vei og treet blir en lenket liste.

Med h=n1h = n-1 er alle operasjonene Θ(n)\Theta(n), og søketreet har ingen
fordel framfor en usortert liste.

Forventet høyde for et tilfeldig bygd tre

Settes nn forskjellige nøkler inn i tilfeldig rekkefølge, er den forventede
høyden Θ(lgn)\Theta(\lg n).

Det er en forventning over alle innsettingsrekkefølger, ikke en garanti for det
enkelte treet.

Skillet er en eksamensfelle: å svare Θ(lgn)\Theta(\lg n) på et spørsmål om
verste tilfelle er galt. Verste tilfelle er Θ(n)\Theta(n).

✏️Eksempel 3: Samme nøkler, to helt ulike trær

Seks lagernumre skal inn i et søketre: 8, 15, 23, 34, 42, 56.

a) Hva blir treets høyde hvis de settes inn i denne rekkefølgen?
b) Finn en innsettingsrekkefølge som gir så lav høyde som mulig, og oppgi
høyden.
c) Hva er inorder-utskriften i de to tilfellene?

a) Nøklene kommer i stigende rekkefølge, så hver eneste innsetting går til
høyre. Treet blir en kjede:

  8
    15
      23
        34
          42
            56

Høyden er 5, altså n1n-1. Et søk etter 56 må
gjennom alle seks nodene.

b) Sett inn medianen først, deretter medianene i hver halvdel:
34, 15, 56, 8, 23, 42.

              34
        15          56
      8    23     42

Høyden er 2, altså lg6=2\lfloor\lg 6\rfloor = 2 — så lavt det går med seks noder.

c) Den samme i begge tilfeller: 8, 15, 23, 34, 42, 56.

Det er hele poenget. Inorder-utskriften avhenger bare av hvilke nøkler
treet inneholder, ikke av hvordan de ligger. Formen påvirker kjøretiden,
ikke innholdet.

Svarformen på eksamen: høyden er ett tall, utskriften er én linje. Ikke
tegn treet med mindre oppgaven ber om det.

📝Oppgave 5
Eksamensnivå, sjanger F

En kandidat skriver i besvarelsen sin: «Søk i et binært søketre er
Θ(lgn)\Theta(\lg n), siden treet halverer søkeområdet i hvert steg.»

Er utsagnet riktig? Svar ja eller nei, og gi et konkret motbevis.

📝Oppgave 6
Eksamensnivå, sjanger H

Du får nn forskjellige heltall i vilkårlig rekkefølge og skal skrive dem ut
sortert.

a) Beskriv en løsning som bygger et binært søketre.
b) Hva er kjøretiden i beste og verste tilfelle, og hvorfor er dette et
dårligere valg enn Merge-Sort?

Kjøretidene samlet

Dette er kapitlets puggeflate. Eksamen er hjelpemiddelfri, så tabellen må ligge
i hodet.

OperasjonKjøretidKrav / egenskap
Tree-InsertO(h)O(h)ny node blir alltid et blad; ingen eksisterende node flyttes
Tree-SearchO(h)O(h)hver sammenligning utelukker ett helt deltre
Tree-MinimumO(h)O(h)følg left så langt det går
Tree-MaximumO(h)O(h)følg right så langt det går
Inorder-Tree-WalkΘ(n)\Theta(n)gir sortert utskrift; tett grense, alle noder besøkes
Preorder- og postorder-traverseringΘ(n)\Theta(n)gir ikke sortert utskrift
Høyden hhΘ(lgn)\Theta(\lg n) forventet, Θ(n)\Theta(n) versteverste tilfelle på sortert input
Sortering via søketreΘ(nlgn)\Theta(n\lg n) beste, Θ(n2)\Theta(n^2) verstedårligere enn Merge-Sort, som garanterer

Én presisering som er verdt å ta med seg. Alle O(h)O(h)-operasjonene er
Θ(n)\Theta(n) i verste tilfelle, siden hh kan bli n1n-1. Skriver du bare
«O(lgn)O(\lg n)» om et søketre uten å nevne balansen, har du lovet noe strukturen
ikke garanterer.
Kontrasten mot maks-haugen fra kap. 3.1:
Maks-haugBinært søketre
Ordneropp–ned: forelder \ge begge barnvenstre–høyre: venstre \le rot \le høyre
Finne maksimumΘ(1)\Theta(1) — ligger på A[1]O(h)O(h) — helt til høyre
Finne minimumΘ(n)\Theta(n) — må lete i alle bladeneO(h)O(h) — helt til venstre
Sortert utskriftkrever Heapsort, Θ(nlgn)\Theta(n\lg n)Inorder-Tree-Walk, Θ(n)\Theta(n)
Formalltid nesten komplettkan bli en lenket liste

Begrepsbank

Begrepsbanken er flashcard- og repetisjonsstoff — den gjentar det du nettopp
har lest. Hopp trygt over ved førstegangslesing; tidsanslaget for kapitlet
gjelder kjernestoffet.

Binært søketre

en trestruktur der hver node har høyst to barn, og der søketreegenskapen holder
i hver node.

Støtter innsetting, søk, minimum og maksimum i O(h)O(h), og sortert utskrift i
Θ(n)\Theta(n).

Formen bestemmes av innsettingsrekkefølgen, og ingenting garanterer at
treet er balansert.

Søketreegenskapen

for hver node x: alle nøkler i venstre deltre er \le x.key, og alle
nøkler i høyre deltre er \ge x.key.

Regelen gjelder i hver node og for hele deltreet, ikke bare for de
nærmeste barna.

Kontrollen er inorder: kommer nøklene ut sortert, holder egenskapen.

`Tree-Insert`

setter en ny nøkkel inn som et blad, på den plassen et søk etter nøkkelen ville
endt.

Kjøretid O(h)O(h).

Ingen eksisterende node flyttes. Derfor bærer treets form et fullstendig
avtrykk av rekkefølgen nøklene kom i.

`Inorder-Tree-Walk`

skriver ut deltreet i rekkefølgen venstre deltre, node, høyre deltre — som gir
sortert utskrift.

Kjøretid Θ(n)\Theta(n), tett grense: hver node besøkes nøyaktig én gang.

Gir ikke innsettingsrekkefølgen. Den er ikke lagret noe sted i treet.

Preorder-traversering

skriver ut noden før deltrærne: node, venstre, høyre.

Kjøretid Θ(n)\Theta(n). Gir ikke sortert utskrift, men starter alltid med
rota.

Nyttig til å skrive ned treets form slik at det kan bygges opp igjen
identisk.

Postorder-traversering

skriver ut noden etter deltrærne: venstre, høyre, node.

Kjøretid Θ(n)\Theta(n). Gir ikke sortert utskrift.

Passer når noe skal gjøres nedenfra og opp, for eksempel å frigjøre
noder.

`Tree-Search`

leter etter en nøkkel ved å sammenligne med noden man står i og gå én vei.

Kjøretid O(h)O(h).

Hver sammenligning utelukker et helt deltre — det er derfor søket er
billig, når treet er balansert.

`Tree-Minimum` og `Tree-Maximum`

følger henholdsvis left- og right-pekerne så langt de går.

Kjøretid O(h)O(h) begge.

Symmetrien er en forskjell fra haugen: i en maks-haug er maksimum
Θ(1)\Theta(1), men minimum Θ(n)\Theta(n).

Høyden hh

antall kanter på den lengste stien fra rota ned til et blad. Et tre med bare
rota har høyde 0.

lgnhn1\lfloor\lg n\rfloor \le h \le n-1.

Alle O(h)O(h)-kjøretidene blir Θ(n)\Theta(n) når treet degenererer, og det gjør
det på sortert input.

Degenerert søketre

et tre der hver node har bare ett barn, slik at treet er en lenket liste med
høyde n1n-1.

Oppstår når nøklene settes inn i stigende eller synkende rekkefølge.

Alle operasjonene blir Θ(n)\Theta(n), og treet har ingen fordel framfor en
usortert liste.

Forventet høyde
Θ(lgn)\Theta(\lg n) for et tre bygget ved å sette inn nn forskjellige nøkler i
tilfeldig rekkefølge.

Det er en forventning over alle innsettingsrekkefølger.

Ikke en garanti. Verste tilfelle er Θ(n)\Theta(n), og spørsmål om verste
tilfelle skal besvares med det.

Felle #2 — søketre mot haug

å blande søketreegenskapen (venstre \le rot \le høyre) med haugegenskapen
(forelder \ge begge barn).

Den mest fremhevede datastrukturfeilen i faget.

Kontrollen: hva ordner regelen? Haugen ordner opp–ned, søketreet ordner
sidelengs.

Blad

en node uten barn.

Nye nøkler settes alltid inn som blader, og det er blader som ligger dypest i
treet.

Høyden er avstanden til det dypeste bladet, målt i antall kanter.

Svarformat for en søketre-håndkjøring

oppgi Inorder-Tree-Walk-utskriften, og rotverdien hvis den er spurt om.

Tegn treet bare når oppgaven ber om det.

Kontrollen før du leverer: er utskriften sortert, og inneholder den
nøyaktig de nøklene som ble satt inn?

Sjanger C — håndkjøring

oppgavetypen der du utfører en navngitt algoritme steg for steg og oppgir
sluttilstanden.

Søketrær og hauger er de to hyppigste strukturene: temaet er registrert i 16 av
de 17 settene i grunnlaget.

Svarformen er kun sluttilstanden. En forklaring av algoritmen gir ingen
ekstra uttelling.

Sjanger D — definisjon med egne ord

oppgavetypen der du skal forklare et begrep presist og kort.

Svarformen er én til to setninger med hovedpoenget først.

«Definér søketreegenskapen» er den hyppigste definisjonsoppgaven i Del 3.

Sjanger F — «stemmer dette?»

oppgavetypen der du får en påstand og skal ta stilling til den.

Svarformen er ja eller nei først, deretter én presis setning.

Et konkret motbevis holder når svaret er nei — ett tre der påstanden
svikter.

Repetisjonsoppgaver

Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.

Skolesaga er en uavhengig læringsressurs og er ikke tilknyttet eller godkjent av Norges teknisk-naturvitenskapelige universitet. Dette er ikke offisielt studiemateriell. Les mer.