De presentatie wordt gedownload. Even geduld aub

De presentatie wordt gedownload. Even geduld aub

1 Datastructuren Zoekbomen II Invoegen en weglaten.

Verwante presentaties


Presentatie over: "1 Datastructuren Zoekbomen II Invoegen en weglaten."— Transcript van de presentatie:

1 1 Datastructuren Zoekbomen II Invoegen en weglaten

2 2 Dit onderwerp  Binaire Zoekbomen: vorige keer  Wat is een binaire zoekboom (eigenschap)  Zoeken  Minimum  Maximum  Opvolger / Voorganger  Binaire Zoekbomen: nu  Een extra query (vb)  Invoegen  Weglaten  Binaire Zoekbomen: hierna  Optuigen: snelle “order queries”  Balanceren: zorg dat de diepte O(log n) blijft

3 3 Binaire zoekboom  Wortel bevat een key (met pointer naar bijbehorend object met extra gegevens …)  Linker deelboom bevat alleen kleinere () keys  Rechter deelboom bevat alleen grotere () keys  Soms sta je toe dat een key vaker voorkomt, soms niet

4 4 Binaire zoekboom  Je kan ook de NIL’s tekenen

5 5 Zoeken in een binaire boom Iterative-Tree-Search(x,k)  while (x != NIL and k != key(x)) do  if ( k < key(x))  then x = left(x)  else x = right(x)  return x; Kost O(h) tijd als boom hoogte h heeft

6 6 Zoeken van Minimum Tree-Minimum(x)  {Zoek het minimum in de boom met wortel x}  while (left(x) != NIL) do  x = left(x);  return x; Het minimum is altijd de “meest linkse” knoop Tijd: O(h) – h hoogte van de boom Het minimum is altijd de “meest linkse” knoop Tijd: O(h) – h hoogte van de boom

7 7 Zoeken van Maximum Tree-Maximum(x)  {Zoek het minimum in de boom met wortel x}  while (right(x) != NIL) do  x = right(x);  return x; Maximum is meest rechtse knoop Tijd: O(h) met h hoogte van de boom Maximum is meest rechtse knoop Tijd: O(h) met h hoogte van de boom

8 8 Opvolgers en voorgangers I  Opvolger van knoop x: 1. Als de rechter- deelboom van x niet leeg is, dan is de opvolger van x het minimum van die rechter-deelboom 2. Als die wel leeg is dan zit die opvolger NIET onder x … Tree-Successor(x)  if (right(x) != NIL)  then return Tree- Minimum(right(x))  else … x

9 9 Opvolger die niet onder x zit  Stel x heeft lege rechter-deelboom  Ga omhoog de boom in, zolang je in rechterdeelbomen zit  Dus je gaat “links- omhoog”  Daarna ga je nog 1 keer een stap omhoog Tree-Successor(x)  if (right(x) != NIL)  then return Tree- Minimum(right(x))  y = parent(x);  while (y != NIL and x == right(y)) do  x = y;  y = parent(y);  return y;

10 10 Tree-successor Tree-Successor(x)  if (right(x) != NIL)  then return Tree- Minimum(right(x))  y = parent(x);  while (y != NIL and x == right(y)) do  x = y;  y = parent(y);  return y;

11 11 Lineair in de hoogte  Alle operaties: Search, Minimum, Maximum, Successor, Predecessor kunnen in O(h) met h de hoogte van de boom  Er bestaan zoekbomen met hoogte O(lg n), bijvoorbeeld neem een complete binaire boom  Later zien we hoe we logaritmische diepte kunnen handhaven

12 12 Veel andere queries  Er zijn veel andere vragen die snel beantwoord kunnen worden mbv een binaire zoekboom  Voorbeeld:  Geef in volgorde alle keys die  k zijn voor een gegeven k (k hoeft niet zelf in de boom te zitten)

13 13 Code voor voorbeeld  Geef in volgorde alle keys die  k zijn voor een gegeven k (k hoeft niet zelf in de boom te zitten)  Idee: recursief algoritme: vergelijk k met waarde van wortel en ga dan in recursie in de delen waar dat nodig is …  Roep aan: ListKG(root.T, k) ListKG(node x, sleutel k)  if (x == NIL) then  Doe niets  else  if key(x)  k then ListKG(left(x)); Druk af key(x); ListKG(right(x))  else ListKG(left(x))

14 14 Analyse voorbeeld  Correct, want …  In goede volgorde want inorder!  Let op rol van NIL’s  Tijd: O(r + h) als we r antwoorden rapporteren en de boom hoogte h heeft ListKG(node x, sleutel k)  if (x == NIL) then  Doe niets  else  if key(x)  k then ListKG(left(x)); Druk af key(x); ListKG(right(x))  else ListKG(left(x))

15 15 Invoegen en weglaten  Invoegen:  Nieuwe knopen kunnen we altijd als blad toevoegen  Het algoritme zoekt een goede plek op waar de nieuwe key als blad kan worden toegevoegd  Weglaten is wat moeilijker (straks)

16 16 Invoegen  Tree-insert voegt een knoop altijd toe in een blad (NIL-knoop)  We lopen eerst naar beneden in de boom en zoeken een blad  Dat blad zit vlakbij z Tree-Insert(T,z)  {z is een knoop met left(z) == right(z) == NIL}  y = NIL;  x = root(T);  while (x != NIL) do  y = x;  {y is steeds de ouder van x}  if (key(z) < key(x))  then x = left(x)  else x = right(x)  {x is een blad van de boom “vlakbij” key(z)}  … en dan …

17

18 18 Invoegen - II  Als we ‘t blad gevonden hebben hangen we z onder y  Als y == NIL: de boom was eerst leeg  Anders kijk je of je z links of rechts onder y moet hangen Tree-Insert(T,z)  y = NIL; x = root(T);  while (x != NIL) do  y = x;  if (key(z) < key(x))  then x = left(x)  else x = right(x)  parent(z) = y;  if (y == NIL)  then root(T) = z (T lege boom)  else  if (key(z) < key(y)  then left(y) = z  else right(y) = z

19 19 Weglaten  Weglaten: als je een blad weglaat: makkelijk  Anders: je kan de knoop niet zomaar weglaten, dan krijg je een gat  Verplaats een andere knoop naar het ontstane gat: welke?  Later: herbalanceren ?

20 20 Weglaten  Bekijk verschillende gevallen:  Knoop heeft geen kinderen (makkelijk)  Knoop heeft alleen linkerkind  Knoop heeft alleen rechterkind (net zo als vorige geval, maar gespiegeld)  Knoop heeft zowel linkerkind als rechterkind

21 21 Weglaten: geval 1  1e geval: knoop heeft geen kinderen  Dan kan je de knoop gewoon weglaten  Ouder van z krijgt een pointer naar NIL erbij Tree-Delete(T,z)  {z is een knoop in de boom T}  if (left(z)==NIL and right(z) == NIL)  then  if (parent(z) == NIL)  then T = NIL {z was de enige knoop, de boom is nu leeg}  elseif (left(parent(z))== z)  then left(parent(z)) = NIL  else right(parent(z)) = NIL  Gooi knoop z weg

22 22 Weglaten – geval 2a  Geval 2a: z heeft maar 1 kind, zeg een linkerkind en een ouder  Dan hangen we dat kind van z direct onder de ouder van z  …  if (left(z) != NIL and right(z) == NIL and parent(z) != NIL)  then  x = left(z);  if (z == left(parent(z))  then left(parent(z)) = x parent(x) = parent(z); Gooi z weg  else right(parent(z)) = x; parent(x) = parent(z); Gooi z weg z is niet de wortel

23 23 Geval 2b  z heeft alleen een linkerkind, geen rechterkind, maar ook geen ouder (is de wortel)  Dan laten we z weg, en wordt het linkerkind de wortel van T  if (left(z) != NIL and right(z) == NIL and parent(z) == NIL)  then  T = left(z);  Gooi z weg z is de wortel

24 24 Weglaten 3  Als z alleen een rechterkind heeft gaat e.e.a. net zo als geval 2 (2a en 2b), met links en rechts verwisseld  if (left(z) == NIL and right(z) != NIL)  … 17 29

25 25 Weglaten 4  Laatste geval: z heeft twee kinderen  Veel lastiger!  Let op: hier verschillen CLRS 2e druk en CLRS 3e druk (en later)  Idee: vind de opvolger van z en verplaats die naar de plek van z

26 26 Weglaten – een nuttig lemma Lemma. Als z twee kinderen heeft, dan heeft de opvolger y (successor) van z geen linkerkind Bewijsidee. Stel dat x een linkerkind is van y. Dan kan je laten zien dat z < x < y en dus is y niet de opvolger van z, tegenspraak. QED z right(z) y x

27 27 Weglaten: twee subgevallen  Laat y de opvolger zijn van x  Geval 4-1: y is het rechterkind van x  Geval 4-2: y is niet het rechterkind van x x x y y

28 28 Weglaten: geval 4-1 (y rechterkind x)  We laten x weg  y is het de opvolger van x  Stel y is het rechterkind van x  We verplaatsen de node van y naar de plek van x  Goed zetten:  Pointer van ouder van x naar x gaat nu naar y  Linkerkind van x wordt linkerkind van y  Als x de wortel was, wordt y de wortel x y y

29 29 Weglaten: geval 4-1 (y rechterkind x)  y = successor(x);  if (parent(y) == x) then:  if (parent(x) == NIL) then: {wortel} Root(T)=y  if (parent(x) != NIL and left(parent(x)==x) {x is linkerkind} left(parent(x) = y parent  if (parent(x) != NIL and right(parent(x)==x) {x is rechterkind} right(parent(x) = y  … x y y

30 30 Weglaten: geval 4-1 (y rechterkind x)  …  parent(left(x))= y  left(y) = left(x)  parent(y) = parent(x)  {Rechterkind van y blijft hetzelfde}  {Nu kan x weggegooid} x y y

31 31 Weglaten: geval 4-2 (y niet rechterkind x)  y wordt verplaatst naar positie van x  Rechterboom van y komt op plek van y x y y

32 32 Stap 1: pointers van en naar de ouder is net als geval 4-1  Oldparenty = parent(y)  if (parent(y) == x) then:  if (parent(x) == NIL) then: {wortel} Root(T)=y  if (parent(x) != NIL and left(parent(x)==x) {x is linkerkind} left(parent(x)) = y parent  if (parent(x) != NIL and right(parent(x)==x) {x is rechterkind} right(parent(x)) = y

33 33 Daarna linker en rechterkinderen  {links net als 4-1}  left(y) = left(x)  parent(left(x))= y  {rechterkind van y nu goed zetten:}  w = right(y)  parent(w) = oldparenty  left(parent(w))=w  right(y) = right(x)  parent(right(y))=y x y y 39 29

34 34 Opmerking  De code in het boek is  Compacter  Moeilijker te snappen dat het correct werkt  Werkt in ongeveer dezelfde tijd

35 35 Tijd  Alle operaties: zoeken, invoegen, weglaten, minimum, maximum opvolger, voorganger, kunnen in O(h) tijd, met h de hoogte van de binaire zoekboom  Verschillende andere operaties kunnen in O(n) tijd, zie ook werkcollege:  Opsommen van knopen in gesorteerde volgorde  …  Hoe groot kan h zijn?

36 36 Hoe groot kan h zijn?  Beste geval: plm. lg n (complete binaire boom)  Slechtste geval: n (elke knoop heeft maar 1 kind)

37 37 Gebalanceerde bomen  Extra werk bij invoegen en weglaten om te zorgen dat de hoogte van de boom O(log n) blijft  Veel verschillende oplossingen hiervoor. Wij bekijken een elegante vorm: de rood-zwart- bomen (red-black trees) en varianten


Download ppt "1 Datastructuren Zoekbomen II Invoegen en weglaten."

Verwante presentaties


Ads door Google