1 / 81

Søgetræer

Søgetræer. Plan. Binære søgetræer Definition Operationer Balancerede binære søgetræer AVL-træer Rød - sort -træer (AA-træer) • B-træer. Eksempel: Søgning efter N . A B E F G H I L M N P R S X L M N P R S X L M N N.

nani
Download Presentation

Søgetræer

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Søgetræer

  2. Plan • Binære søgetræer Definition Operationer • Balancerede binære søgetræer AVL-træer Rød-sort-træer (AA-træer) • • B-træer

  3. Eksempel: Søgning efter N. A B E F G H I L M N P R S X L M N P R S X L M N N Binær søgningi et sorteret array • Metode: • Opdel arrayet i to (næsten) lige store dele. • Afgør i hvilken af de to dele, nøglen skal findes. • Fortsæt søgningen i denne del på samme måde.

  4. I P E M S A G X N L R B F H Binært søgetræ • Binær søgning kan beskrives ved et binært søgetræ: • Et binært søgetræ, er et binært træ, hvor der for enhver knude X gælder, at alle knuder i dets venstre undertræ er mindre end X, og alle knuder i dets højre undertræ er større end X.

  5. public class BinarySearchTree implements SearchTree { public Comparable find(Comparable x); public void insert(Comparable x); public void remove(Comparable x); public isEmpty(); public makeEmpty(); public printSorted(); public Comparable findMin(); public Comparable findMax(); } Binært søgetræ som abstrakt datatype

  6. class BinaryNode { BinaryNode(Comparable e, BinaryNode lt, BinaryNode rt) { element = e; left = lt; right = rt; } Comparable element; BinaryNode left, right; } public class BinarySearchTree { ... BinaryNode root; } Intern repræsentation

  7. public Comparable find(Comparable x) { return find(x, root).element; } Comparable find(Comparable x, BinaryNode t) { while (t != null) { if (x.compareTo(t.element) < 0) t = t.left; else if (x.compareTo(t.element) > 0) t = t.right; else return t; } throw new ItemNotFoundException(x.toString()); } Søgning

  8. 7 7 9 2 9 2 1 5 1 5 3 3 6 Indsættelse Indsættelse af 6 • Der foretages en mislykket søgning, og den nye knude indsættes der, hvor søgningen stopper.

  9. public void insert(Comparable x) { root = insert(x, root); } BinaryNode insert(Comparable x, BinaryNode t) { if (t == null) t = new BinaryNode(x, null, null); else if (x.compareTo(t.element) < 0) t = insert(x, t.left); else if (x.compareTo(t.element) > 0) t = insert(x, t.right); else throw new DuplicateItemException(x.toString()); return t; } Indsættelse

  10. 7 2 9 18 15 15 18 1 1 5 5 2 9 11 3 3 11 Sletning Sletning af roden • Erstat roden med den knude, der er mindst i rodens højre undertræ. • Denne knude befinder sig længst til venstre i rodens højre undertræ. • Hvis det højre undertræ er tomt, fjernes roden blot fra træet.

  11. public void remove(Comparable x) { root = remove(x, root); } BinayNode remove(Comparable x, BinaryNode t) { if (t == null) throw new ItemNotFoundException(x.toString()); if (x.compareTo(t.element) < 0) t.left = remove(x, t.left); else if (x.compareTo(t.element) > 0) t.right = remove(x, t.right); else if (t.right != null) { // x found t.element = findMin(t.right).element; t.right = removeMin(t.right); } else t = t.left; return t; } Sletning

  12. t BinaryNode findMin(BinaryNode t) { if (t == null) throw new ItemNotFoundException(); while (t.left != null) t = t.left; return t; } t.left t.right BinaryNode removeMin(BinaryNode t) { if (t == null) throw new ItemNotFoundException(); if (t.left == null) return t.right; t.left = removeMin(t.left); return t; }

  13. Alternativ implementering af sletning BinaryNode remove(Comparable x, BinaryNode t) { if (t == null) throw new IntemNotFoundException(); lastNode = t; if (x.compareTo(t.element) < 0) t.left = remove(x, t.left); else { deletedNode = t; t.right = remove(x, t.right); } if (t == lastNode) { if (t == null || x.compareTo(t.element) != 0) throw new IntemNotFoundException(x.toString()); deletedNode.element = t.element; deletedNode = null; t = t.right; } return t; }

  14. 7 2 15 18 void printSorted(BinaryNode t) { if (t != null) { printSorted(t.left); System.out.println(t.element); printSorted(t.right); } } 1 5 9 3 11 Inorder-traversering af træet Udskrivning af elementerne i sorteret rækkefølge

  15. BinaryNode FindKth(int k, BinaryNode t) { if (t == null) throw new ItemNotFoundException(); int leftSize = t.left != null ? t.left.size : 0; if (k == leftSize + 1) return t; if (k <= leftSize) return findKth(k, t.left); return findKth(k - (leftSize + 1), t.right); } t leftSize Find det k’te mindste element Vedligehold for enhver knude t en variabel, size, der angiver antallet af knuder i det træ, der har t som rod.

  16. 1 3 5 9 Kompleksitet Kompleksiteten af søgning, indsættelse og sletning afhænger af søgetræets udseende. I alle tre tilfælde er tiden proportional med længden af den anvendte søgevej. I bedste fald, nemlig når træet er fuldt, udføres cirka log2N sammenligninger. I værste fald, nemlig når træet er en lineær liste, udføres N sammenligninger.

  17. Det gennemsnitlige tilfælde Hvis hvert element indsættes i tilfældig rækkefølge i et fra starten tomt binært søgetræ, vil længden af søgevejen i det frembragte træ i gennemsnit være 1.38 log2N. I praksis er udførelsestiden for de tre grundoperationer O(logN) for tilfældigt input. Det er dog endnu ikke blevet påvist analytisk.

  18. Balancerede søgetræer • Balancering er en teknik, der garanterer, at de værste tilfælde ved søgning ikke forekommer. • Ideen er at omorganisere træet under indsættelse og sletning, så det bliver fuldt (eller næsten fuldt). • Et fuldt træ siges at være i perfekt balance. For enhver knude gælder nemlig, at antallet af knuder i dens venstre undertræ er lig med antallet af knuder i dens højre undertræ. • I det følgende præsenteres en række datastrukturer, der garanterer O(logN) kompleksitet for såvel søgning, indsættelse som sletning.

  19. BinarySearchTree buildTree(Comparable[] a) { sort(a); BinarySearchTree bst = new BinarySearchTree(); bst.root = buildTree(a, 0, a.length - 1); return bst; } Opbygning af et balanceret søgetræ ud fra en tabel af poster BinaryNode buildTree(Comparable[] a, int low, int high) { if (low > high) return null; int mid = (low + high) / 2; return new BinaryNode(a[mid], buildTree(a, low, mid - 1), buildTree(a, mid + 1, high)); }

  20. AVL-træer(Adelson-Velskii og Landis, 1962) • Et AVL-træ er et binært søgetræ, som opfylder følgende egenskab: • For enhver knude i træet gælder, at højden af dens venstre undertræ og højden af dens højre undertræ højst afviger med 1.

  21. 15 18 (3) 8 5 9 7 (1) (2) 11 2 (0) (1) (0) (0) (0) Eksempel på et AVL-træ • Højden af er træ er det maksimale antal af kanter fra træets rod til et af dets blade. For et tomt træ vedtages, at højden er -1.

  22. X H H-2 H-1 SH-2 SH-1 Indsættelse i AVL-træ Indsættelse i X’s venstre undertræ kan ødelægge AVL-egenskaben. I det følgende betegner X den “dybeste” knude, som er rod i et træ, der ikke længere opfylder AVL-egenskaben.

  23. X X X X Indsættelse i AVL-træ4 tilfælde Ved indsættelse i et af X’s undertræer er der 4 mulige tilfælde: 1. Indsættelsen sker i det venstre undertræ af X’s venstre søn. 2. Indsættelsen sker i det højre undertræ af X’s venstre søn. 3. Indsættelsen sker i det venstre undertræ af X’s højre søn. 4. Indsættelsen sker i det højre undertræ af X’s højre søn. Tilfælde 1 og 4 er symmetriske. Tilfælde 2 og 3 er symmetriske.

  24. X k2 k1 k1 k2 C C B B A A En højrerotation genskaber balancen Tilfælde 1

  25. k2 X k2 k1 k1 C C A A B B En højrerotation genskaber ikke balancen Tilfælde 2

  26. k1 X k3 k3 k3 k2 k2 k1 k1 k2 D D C B C D A A A C B B Tilfælde 2(fortsat) En venstre-højre-dobbeltrotation genskaber balancen

  27. k2 X k2 k1 k1 C C B B A A BinaryNode rotateWithLeftChild(BinaryNode k2) { BinaryNode k1 = k2.left; k2.left = k1.right; k1.right = k2; return k1; } Implementation af højrerotation

  28. k1 X k3 k2 k3 k3 k2 k1 k1 k2 D D D C C A A A C B B B BinaryNode doubleRotateWithLeftChild(BinaryNode k3) { k3.left = rotateWithRightChild(k3.left); return rotateWithLeftChild(k3); } Implementation af dobbeltrotation

  29. Hjælpemetode int height(BinaryNode t) { return t == null ? -1 : t.height; } Højdeinformation I klassen BinaryNode tilføjes et ekstra felt: int height. height angiver højden af det træ, der har den angivne knude som rod.

  30. Implementering af metoden insert BinaryNode insert(Comparable x, BinaryNode t) { if (t == null) t = new BinaryNode(x, null, null); else if (x.compareTo(t.element) < 0) { t.left = insert(x, t.left); if (height(t.left) - height(t.right) == 2) if (x.compareTo(t.left.element) < 0) t = rotateWithLeftChild(t);// case 1 else t = doubleRotateWithLeftChild(t);// case 2 } else if (x.compareTo(t.element) > 0 ) { ... // case 3 or 4 } else throw new DuplicateItemException(); t.height = Math.max(height(t.left), height(t.right)) + 1; return t; }

  31. k2 X k2 k1 k1 C C B B A A BinaryNode RotateWithLeftChild(BinaryNode k2) { BinaryNode k1 = k2.left; k2.left = k1.right; k1.right = k2; k2.height = Math.max(height(k2.left), height(k2.right)) + 1; k1.height = Math.max(height(k1.left), k2.height) + 1; return k1; } Opdatering af height

  32. 60 20 70 70 85 10 50 65 5 30 65 55 60 20 85 10 50 65 5 55 30 65 45 Eksempel på indsættelse 45 indsættes: fortsættes

  33. 60 70 20 85 10 50 65 70 5 55 30 65 45 60 50 85 20 65 55 10 30 5 65 45 Ubalance i 60: Venstrerotation ved 20: fortsættes

  34. 60 50 85 20 65 55 70 70 60 10 30 5 65 45 50 20 10 55 30 85 65 5 65 45 Højrerotation ved 60: slut

  35. Effektiviteten af AVL-træer Højden H af et AVL-træ tilfredsstiller H < 1.44 log2(N+2) - 1.328 I et tilfældigt konstrueret træ er højden meget tæt på log2(N).

  36. Problem Et skakbræt med 8 x 8 felter kan dækkes af 32 dominobrikker, som hver dækker 2 af brættets felter. To af brættets hjørnefelter på samme diagonal skæres væk. Kan 31 brikker nu dække brættet? Farvelægning løser problemet.

  37. Rød-Sort-træer(Bayer, 1972) • Et Rød-Sort-træ er et binært søgetræ, som opfylder følgende 4 egenskaber: • 1. Enhver knude er farvet enten rød eller sort. • 2. Roden er sort. • 3. Hvis en knude er rød, så er dens sønner sorte. • 4. Enhver vej fra roden til en null-reference indeholder det samme antal sorte knuder.

  38. 30 70 15 85 10 20 60 50 65 80 90 5 40 55 Eksempel på et Rød-Sort-træ 0. Træet er et binært søgetræ. 1. Enhver knude er farvet enten rød eller sort. 2. Roden er sort. 3. Hvis en knude er rød, så er dens sønner sorte. (null regnes for sort) 4. Enhver vej fra rod til blad indeholder det samme antal sorte knuder. (3)

  39. Effektiviteten af Rød-Sort-træer Højden H af et Rød-Sort-træ tilfredsstiller H ≤ 2 log2(N+1) I et tilfældigt konstrueret træ er højden meget tæt på log2(N). (faktisk 1.002 log2(N))

  40. Indsættelse i Rød-Sort-træer En ny knude indsættes som nyt blad i træet. Hvis den nye knude farves sort, ødelægges rød-sort-egenskab 4, og det er ikke umiddelbart klart, hvorledes egenskaben kan genoprettes. Hvis den nye knude farves rød, og dens far samtidig er sort, vil ingen af rød-sort-egenskaberne blive ødelagt. Hvis dens far derimod er rød, ødelægges rød-sort-egenskab 3. Vi skal sørge for, at en ny knude indsættes som rød søn af en sort far. Hvordan? Svar: Benyt rotationer og farveskift.

  41. P P G P S X X G G B A B C C B C A A S S X rotateWithLeftChild(G) Skift farve på P og G Behandling af 5 tilfælde X: den aktuelle røde knude. P: X’s røde far. G: X’s farfar (må nødvendigvis være sort) S: X’s farbror Tilfælde 1: X er venstre-søn til P, P er venstre-søn til G, og S er sort.

  42. G X X S G G P S S P P X P X rotateWithLeftChild(G) A A A C C C A C B1 B2 B2 B1 B1 B2 B1 B2 G rotateWithRightChild(P) S Skift farve på X og G Tilfælde 2: X er højre-søn til P, P er venstre-søn til G, og S er sort.

  43. G G P S P S X X C C B B A A Skift farve på P, S og G. Hvis G er rod, så farv G sort. Tilfælde 3: X er højre-søn til P, P er højre-søn til G, og S er sort. Er symmetrisk med tilfælde 1 Tilfælde 4: X er venstre-søn til P, P er højre-søn til G, og S er sort. Er symmetrisk med tilfælde 2 Tilfælde 5: Både P og S er røde.

  44. I tilfælde 5 kan en rød-farvning af G ødelægge rød-sort-egenskab 3. Dette problem kan dog let løses ved en enkelt-rotation (tilfælde 1 og 3) eller en dobbelt-rotation (tilfælde 2 og 4). Ingen af disse rotationer giver i sig selv anledning til yderligere rotationer. Rotationerne af type 5 kræver adgang til X’s oldefar. I lærebogens algoritme vedligeholdes således følgende referencer: current: den aktuelle knude parent: den aktuelle knudes far grand: den aktuelle knudes bedstefar great: den aktuelle knudes oldefar Disse referencer kan undværes, hvis indsættelse foretages rekursivt. Dette vil blive beskrevet i det følgende.

  45. Implementering I klassen BinaryNode tilføjes feltet int color; I klassen RedBlackTree defineres konstanterne static final int RED = 0; static final int BLACK = 1; I stedet for null-referencer benyttes objektet nullNode: static BinaryNode nullNode; static { nullNode = new BinaryNode(null); nullNode.left = nullNode.right = nullNode; nullNode.color = BLACK; }

  46. public void insert(Comparable x) { root = insert(x, root, true); root.color = BLACK; } BinaryNode insert(Comparable x, BinaryNode t, boolean rightChild) { if (t == nullNode) { t = new BinaryNode(x, nullNode, nullNode); t.color = RED; } else { if (t.left.color == RED && t.right.color == RED) { t.color = RED; t.left.color = t.right.color = BLACK; } if (x.compareTo(t.element) < 0) { t.left = insert(x, t.left, false); if (rightChild && t.color == RED && t.left.color == RED) t = rotateWithLeftChild(t); if (t.left.color == RED && t.left.left.color == RED) { t = rotateWithLeftChild(t); t.color = BLACK; t.right.color = RED; } } else if (x.compareTo(t.element) > 0) {...} else throw new DuplicateItemException(x.toString()); } return t; }

  47. t.right = insert(x, t.right, true); if (!rightChild && t.color == RED && t.right.color == RED) t = rotateWithRightChild(t); if (t.right.color == RED && t.right.right.color == RED) { t = rotateWithRightChild(t); t.color = BLACK; t.left.color = RED; } Behandling af de 2 symmetriske tilfælde left erstattes med right right erstattes med left rightChild erstattes med !rightChild

  48. 30 70 70 15 85 85 10 20 60 30 50 65 80 90 5 15 40 55 10 20 60 50 65 80 90 5 40 55 fortsættes 45 Eksempel på indsættelse 45 indsættes: Farveskift på 50, 40 og 55:

  49. 30 15 10 20 60 70 50 65 80 90 5 85 85 40 55 30 15 60 50 45 10 20 70 40 55 65 5 45 80 90 Højrerotation ved 70 med farveskift af 60 og 70: slut

  50. AVL-træer contra Rød-Sort-træer Et rød-sort-træ er sædvanligvis mere effektivt: Indsættelse i et AVL-træ kræver (i værste tilfælde) 2 gennemløb af en vej (ned til et blad og tilbage til roden), mens indsættelse i et rød-sort-træ kan klares med 1 gennemløb. NB. I den rekursive implementation for et rød-sort-træ benyttes 2 gennemløb. Implementation af sletning i såvel AVL- som rød-sort-træer er vanskelig.

More Related