Mehrdimensionale Suchstrukturen • Gegeben: - Menge S von N Punkten in Rk - Familie U von Untermengen von Rk (Ranges) - dÎU Effiziente Algorithmen Teil 4: Mehrdimensionale Suchstrukturen • Gesucht: - Vorverarbeitung von S, so dass Abfragen der Art: ``Berichte alle Punkte in S∩ d´´ effizient berichtet werden können. • Beispiel: Datenbankabfragen Petra Mutzel 1 2 Anwendungsbereiche Charakterisierung (1) • • • • • • • • • • Welche Datentypen werden gespeichert? Datenbanken Computergraphik / Computer Vision Computer-Aided Design Geographische Informationssysteme Bildverarbeitung Mustererkennung Document-Retrieval Data Mining ... - S ist ungeordnete Menge (z.B. Index) - S ist kartes. Produkt S 1? S 2 ?...? S k geordn. Mengen • Dimension: - k ist kleiner gleich 10 • Operationen: - Find, Insert, Delete, (Pred., Succ., Min, Max) • Welche Speichermedien? - intern vs. extern 3 4 Charakterisierung (2) Wir betrachten folgende Abfragen: • Welche Objekttypen werden gespeichert? • Punkt-Abfrage (Point Query): - Punkte, Container (z.B. Quader in 3D), komplexer - Lage fixiert oder beweglich? - Ist ein gegebener Datenpunkt in SÎRk enthalten, und falls ja, dann finde diesen. • Welche Abfragen und wie oft? - Ist Punkt enthalten? - Aufzählung aller Punkte, die in gewünschtem k-dim. Bereich liegen - Welche Punkte liegen in der Nähe eines Punktes? - Finde die n nächsten Nachbarn eines Punktes - Exakte vs. partielle Abfragen - Einmalige vs. viele Abfragen • Bereichsabfrage (Range Query): - Berichte alle Punkte aus S, deren k Schlüssel in den gewünschten Bereichen liegen. 5 6 1 Einfache Datenstrukturen ``Fixed Grid´´ Methode • Sequentielle Liste - Aufwand: O(N k) • Invertierte Liste (Knuth 1973) Name X-key Y-key D C O M 5 35 25 50 45 40 35 10 X-key D O C M - Sortierte Liste pro Schlüssel - Durchschnittlicher Aufwand: O(N1-1/k) - Aufwand: O(N k) • Suchraum wird in gleiche Teile (Buckets ) der Größe r aufgeteilt, wobei r der Suchradius ist • Realisiert als k-dim. Array mit einem Eintrag per Bucket; jeder Bucket enthält Punkte in Form einer einfachen Liste • Durchschnittlicher Suchaufwand für Bereichssuche (Bentley 1977): O(F 2k), wobei F die Anzahl der berichteten Punkte ist • Effizient, wenn fixer Radius und Datenpunkte gleichmäßig im Raum verteilt sind (Kartographie) • Teilt den Raum auf Y-key M O C D 7 8 Region Quadtrees Point Quadtrees • Repräsentation eines 2-dim. Binärbildes (Region Data) • Rekursive Teilung eines 0/1- Bereiches in vier gleich große Quadranten, STOP falls Block nur 0 oder nur 1 enthält • Suchbaum mit Grad 4 (s. Beispiel) • Jedes Kind eines Knotens repr. Quadranten (NW,NE,SW,SE) • Blätter=Aufteilung nicht weiter notwendig • Blätter sind entweder ``weiß´´ oder ``schwarz´´, innere Knoten sind ``grau´´ • Aufbau: bottom- up mit ``Morton Order´´ • Eingeführt von Finkel & Bentley 1974 • Multidimensionale Verallgemeinerung von binären Suchbäumen • Verheiratung von ``Fixed Grid´´ mit binären Suchbäumen • Rekursive Teilung an Datenpunkten in jeweils vier Teile: NW,NE,SW, SE • Hier Annahme: - k=2, Verallg. einfach - Jeder Punkt wird nur einmal besetzt 9 10 Beispiel: Point Quadtree zu Beispiel A G H K C B L J F D J F M N I E K L H G B I A M D C E N 11 12 2 Point Quadtrees: Datenstruktur Point Quadtrees: Operation Insert • Jeder innere Knoten enthält • Ähnlich wie für binäre Suchbäume: - Suche den Punkt (nach x und y-key) - Wenn Blatt erreicht ist, dann bestimme Position, an die eingefügt werden muss. - Pointers zu Kindern NW,NE,SW,SE - SON(P,I): gibt Kind im Quadranten I von Knoten P an - XCOORD, YCOORD: Koordinaten von Punkt - NAME: Information über Punkt (z.B. Name) 13 14 Beispiel: Insert Z Point Quadtree zu Beispiel: Insert Z A G H K J C B L J F D Z F M N I E K L H G B I A M D C E Z N 15 Insert: PT_COMPARE quadrant procedure PT_COMPARE(P,R); /* Return the quadrant of the point quadtree rooted at node R in which node P belong. */ begin value pointer node P,R; return(if XCOORD(P) < XCOORD(R) then if YCOORD(P) < YCOORD(R) then ’SW‘ else ’NW‘ else if YCOORD(P) < YCOORD(R) then ’SE‘ else ’NE‘); end; 17 16 procedure PT:INSERT(P,R); /* Attempt to insert node P to tree rooted at node R. */ begin value pointer node P reference pointer node R; pointer node F; quadrant Q; if null(R) then R f P /* Tree at R is initially empty */ else begin while not(null(R)) and not(EQUAL COORD(P,R)) do begin F f R; /* Remember the father */ Q f PT_COMPARE(P,R); R f SON(R,O); end; if null(R) then SON(F,Q)f P;/* P is not already in tree */ end 18 end; 3 Point Quadtrees: Analyse Aufbau Point Quadtrees: Deletion • Aufbau eines Point Quadtrees: • Problem: - Aufwand ist äquivalent zur Gesamtpfadlänge = Kosten, um nach allen Elementen einmal zu suchen • Gesamtpfadlänge: - Geht nicht so leicht wie bei binären Suchbäumen - Beispiel: Deletion of A - Hängt von Reihenfolge der Einfügungen der Punkte ab - Empirisch: N log 4 N (Finkel & Bentley) - Worst Case: N(N-1)/2 (Übung) • Aufwand für Insert und Search - Empirisch: O(log 4 N) - Worst Case: O(N) - Re-Balancing Methoden sind möglich (Übung) 19 Beispiel: Deletion 20 Beispiel: Deletion G G H K F D J C B L H K I A C B L E F D J I E A M M N N 21 22 Point Quadtrees: Deletion Point Quadtrees: Deletion • Problem: • Problem: - Unterbäume des gelöschten Knotens müssen eventuell neu eingefügt werden, denn sie sind nicht mehr im richtigen Quadranten bzgl. der neuen Wurzel - Unterbäume der Wurzel müssen neu eingefügt werden - Alle Knoten mit deren Unterbäumen, die in der Zwischenregion liegen, müssen neu eingefügt werden. • Idee: - Wähle in jedem Unterquadranten des zu entfernenden Knotens einen Kandidaten aus, der am nächsten bei x oder y-Koordinate ist. - Wähle aus diesen vier Kandidaten dann den besten aus. - Original-Vorschlag war daher: alle diese Unterbäume neu einfügen - Besser: Vorschlag von Samet: 23 24 4 Wunsch: Finde einen Punkt Z, so dass die Beispiel: Zwischen-Region def. durch Z und A leer ist Deletion: FIND_CANDIDATE(P,Q) G H K F D J C B L I E A M N Problem: Z muss nicht existieren! 25 Kriterium 1: Wähle denjenigen, der am nächsten bei A liegt bzgl. x und y Beispiel: Kandidaten nach FIND_CAND Punkt mit Kriterium 1 muss nicht existieren: Bsp Pointer node procedure FIND_CANDIDATE(P,Q) /* P pointer to the son in quadrant Q of the node to be deleted. OPQUAD(Q) gives quadrant 180 degrees apart from Q*/ begin value pointer node P; value quadrant Q; if null(P) then return(INF(Q)); while not(null(SON(P,OPQUAD(Q)))) do P f SON(P,OPQUAD(Q)); return(P); end; 26 Kriterium 1: Wähle denjenigen, der am nächsten bei A liegt bzgl. x und y Beispiel: Kandidaten nach FIND_CAND Punkt mit 2Kriterium 1 muss nicht existieren: Bsp Kriterium (NEU): Wähle denjenigen mit min (|x 2-x 1 |,|y 2-y1 |) G G H K F D J C B L H K I A C B L E F D J I E A M M Kriterium 1 garantiert, dass Zwischenregion leer ist N N Kriterium 1 garantiert, dass Zwischenregion leer ist 27 Kriterium 2 garantiert, dass höchstens ein anderer Kandidat innerhalb der Zwischenregion liegt 28 Point Quadtrees: Deletion - Vorgehen Point Quadtrees: ADJQUAD() • Sei P der zu entfernende Punkt, R ist Wurzel • Falls P kein oder nur ein Kind hat: einfach • Sonst: • Sei P der entfernte Punkt und J der beste Kandidat, J liegt in Quadrant Q bzgl. P, S=CQ, R=P, F=P • ADJQUAD(CQ,OQ,S,F,R): Umbau von SON( F,S) des Quadranten CQ des Baumes mit Wurzel R - Bestimme die vier Kandidaten pro Quadrant Bestimme den besten Kandidaten nach Kriterien 1,2 Sei J bester Kandidat, J liegt in Quadrant Q bzgl. P: Kopiere xcoord, ycoord , name Rekursiver Umbau des Quadranten CQUAD(Q) mit Hilfe von ADJQUAD() - Rekursiver Umbau des Quadranten CCQUAD(Q) mit Hilfe von ADJQUAD() - Rekursiver Umbau des Quadranten Q mit Hilfe von NEWROOT() 29 - Sei T=Kind von F im Quadranten S - Falls T in der Zwischenregion liegt, dann l Füge alle Knoten des Teilbaums mit Wurzel T neu in den Teilbaum mit Wurzel R ein. - Sonst l /* keine Neueinfügung für T sowie SON(T,CQ) sowie SON(T,OPQUAD(OQ)) nötig */ l Rekursiver Umbau des OPQUAD(CQ) Quadranten von Kind von T: ADJQUAD(CQ,OQ,OPQUAD(CQ) ,T,R) l Rekursiver Umbau des OQ Quadranten von Kind von T: ADJQUAD(CQ,OQ,OQ,T,R) 30 5 Point Quadtrees: NEWROOT() Beispiel: • Sei P der entfernte Punkt und J der beste Kandidat, J liegt in Quadrant Q bzgl. P, R=P, S=Q, F=Father(S) • NEWROOT(Q,S,R, F): Umbau des Quadranten S mit Father=F, G H K - Falls Quadrant OPQUAD(Q) von S leer ist, dann l /* S =Q */ l Neueinfügung aller Knoten im CQUAD(Q) Quadranten von R l Neueinfügung aller Knoten im CCQUAD(Q) Quadranten von R F D J C B L - Sonst I E A l Rekursiver Umbau von SON(S,CQUAD(Q)) durch Aufruf von ADJQUAD(Q,CQUAD(Q),CQUAD(Q),S,R) l Rekursiver Umbau von SON(S,CCQUAD(Q)) durch Aufruf von ADJQUAD(Q,CCQUAD(Q),CCQUAD(Q),S,R) l Rekursiver Umbau des OPQUAD(Q) Quadranten von S: NEWROOT(Q,SON(S,OPQUAD(Q)),R,S) M N 31 32 Quadtree zu Beispiel nach Deletion von A Beispiel nach Deletion von A B G H K D J L F J F M N C B E I K D H G C L E I M N 33 procedure PT_DELETE(P,R); /* Delete node P from the point quadtree rooted at node R. If the root of the tree was deleted, then reset R. */ begin value pointer node P; reference pointer node R; pointer node; J quadrant Q; if HAS_NO_SONS(P) or HAS_ONLY_ONE_SON(P) then /* Set P‘s father to the son of P if one exists; otherwise, return NIL */ begin J f FIND_FATHER(P); if null(J) then R f NON_EMPTY_SON(P) else SON(J,SONTYPE(P)) f NON_EMPTY_SON(P); returntoavail(P); return ; end 35 34 else /* Find the ‚best‘ replacement node for P and rearrange the tree */ begin J f ‚best‘ replacement node for P Q f quadrant of P containing J; /* Copy coordinate values of node J to node P */ XCOORD(P) f XCOORD(J); YCOORD(P) f YCOORD(J); /* Rearrange the remaining quadrants */ ADJQUAD(CQUAD(Q),OPQUAD(Q),(CQUAD(Q),P,P); ADJQUAD(CQUAD(Q),OPQUAD(Q),CCQUAD(Q),P,P); NEWROOT(Q),SON(P,P);/* Rearrange quadrant Q */ /* Return node J to AVAIL since it is no longer needed */ returntoavail(J); end; 36 end; 6 recursive procedure ADJQUAD(Q,D,S,F,R); /* Rearrange subquadrant SON(F,S) of quadrant Q. R is the node that has been deleted. D is the quadrant in which nodes in the subquadrant rooted at SON(F,S) may have to be reinserted. Otherwise, they remain in quadrant Q. */ begin value quadrant Q,D,S; value pointer node F,R; pointer node T; T f SON(F,S); if null(T) then return /* An empty link /* else if PT_COMPARE(T,R)=Q then /* Node T and subquadrants SON(T,Q) and SON(T,OPQUAD(D)) need no reinsertion */ begin /* Rearrange subquadrant SON(T,OPQUAD(Q)) */ ADJQUAD(Q,D,OPQUAD(Q);T;R); /* Rearrange subquadrant SON(T,D) */ ADJQUAD(Q,D,D,T,R); end else /* Unlink subquadrant S from F so that it will not be found upon reinsertion should it belong to the same quadrant */ begin 37 recursive procedure NEWROOT(Q,S,R,F); /* Rearrange the quadrant containing the replacement node for the deleted node - - i.e., quadrant Q of node R. R is the node that has been deleted. S is the root of the subquadrant currently being processed and i s the son of F.*/ begin value quadrant Q; value pointer node S,R,F; if null(SON(S,OPQUAD(Q))) then /* S is the replacement node. Insert ist subquadrants and reset the father of the replacement node. */ begin INSERT_QUADRANT(SON(S,CQUAD(Q)),R); INSERT_QUADRANT(SON(S,CCQUAD(Q)),R); i f R ? F then /* Reset the father of replacement node /* SON(F,OPAD(Q) f SON(S,Q) else SON(F,Q) f SON(S,Q); f NIL; INSERT_QUADRANT(T,R); end; end; SON(F,S) 38 else /* Rearrange the quadrants adjacent to quadrant Q of the tree rooted at S and reapply NEWROOT to SON(S,OPQUAD(Q)) */ begin /* Rearrange subquadrant SON(S,CQUAD(Q)) */ ADJQUAD(Q,CQUAD(Q),CQUAD(Q),S,R); /* Rearrange subquadrant SON(S,CCQUAD(Q)) */ ADJQUAD(Q,CCQUAD(Q),CCQUAD,S,R); /* Rearrange subquadrant SON(S,OPQUAD(Q)) */ NEWROOT(Q,SON(S,OPQUAD(Q)),R,S); end; end; 39 40 end Point Quadtrees: Analyse Deletion Pseudo Quadtrees • Theoretisch (Bentley 1988): • Overmars und van Leeuwen 1982 • Idee: - Aufwand bei gleichmäßig verteilten Daten für die Anzahl der Neueinfügungen geht um 83% zurück gegenüber der Neueinfügung aller Teilbäume. - Rekursive Aufteilung des Raumes an Punkten, die nicht Datenpunkte sind, in Quadranten, Unterquadranten, etc., bis jeder Unterquadrant höchstens einen Datenpunkt enthält. • Empirisch (Bentley 1988): - Empirisch: N log 4 N vs. deutlich größer in Original - Gesamtpfadlänge verringert sich leicht vs. deutlich Verlängerung in Original • Worst Case: - O(N2) • Deletion sehr komplex! • Alternative: Pseudo Quadtrees 41 42 7 Pseudo Quadtrees: Beispiel (0,100) Pseudo Quadtree für Beispiel (100,100) (40,50) (60,75) TORONTO 70,70 ’ y (80,65) BUFFALO (40,50) (35,40) (5,45) DENVER CHICAGO (25,35) (26,37) OMAHA (0,0) (70,70) (85,15) ATLANTA TORONTO BUFFALO (65,12) (50,10) Mobile x’ (26,37) (65,12) DENVER OMAHA CHICAGO ATLANTA MIAMI MOBILE (90,5) MIAMI (100,0) 43 44 Pseudo Quadtrees: Point Quadtrees: Diskussion • Aufbau: • Nachteile bei höheren Dimensionen: - Für je N Datenpunkte im k-dim. Raum existiert ein Partitionierungspunkt, so dass jeder Quadrant höchstens + N/(k+1) + Datenpunkte enthält. • Analyse: - Dann besitzt der Pseudo Quadtree eine Tiefe von höchstens + logk+1N+ und kann in Zeit O(N logk+1N) gebaut werden. - An jedem Knoten des Baumes sind k Vergleiche notwendig (um den Quadranten zu bestimmen) - Hoher Speicherplatzverbrauch: Jedes Blatt benötigt k viele NULL Pointer, auch jeder innere Knoten besitzt immer wieder NULL Pointer - Speicherplatzverbrauch pro Knoten: k+2k+1 Wörter für Koordinaten, Kinder und Info 45 K-D Trees: 46 K-D Tree: Beispiel (0,100) - Binärer Suchbaum mit der Eigenschaft, dass in jeder Tiefe nach einer anderen Dimension orthogonal aufgeteilt wird. - Z.B. k=2: nach x-Koordinaten auf den Schichten mit gerader Nummer (Beginn bei Schicht 0), nach yKoordinaten auf den ungeraden Schichten. - Aufteilung basiert auf den Datenpunkten - BSP Trees (Fuchs, Kedem, Naylor 1980): K-D Trees, bei denen nicht orthogonal aufgeteilt wird (beliebige Hyperebenen) y (80,65) BUFFALO (5,45) DENVER (25,35) OMAHA • Beispiel: 47 (100,100) (60,75) TORONTO ’ • Bentley 1975 • Idee: (0,0) (85,15) (35,40) ATLANTA CHICAGO (50,10) Mobile (90,5) MIAMI x’ (100,0) 48 8 K-D Trees: K-D Tree: Einfügen (0,100) • Datenstruktur: - LEFT, RIGHT: linkes und rechtes Kind (referenziert als SON(P,I) bzw. LOSON(P) und HISON(P)) - XCOORD, YCOORD, ... - NAME - DISC: Diskriminator bzgl. k-tem Schlüssel - Abmachung für Diskriminatoren: gleiche Schlüsselwerte befinden sich im rechten Teilbaum (100,100) (60,75) TORONTO ’ Z y (5,45) DENVER (25,35) OMAHA (0,0) 49 (85,15) (35,40) ATLANTA CHICAGO (50,10) Mobile (90,5) MIAMI x’ K-D Trees: INSERT Adaptive K-D Trees • Analog zu binären Suchbäumen: • Idee: - Wir suchen den Punkt abwechselnde basierend auf den k Schlüsseln - Wenn das Blatt erreicht ist, haben wir die EinfügePosition gefunden Form des Baumes hängt von Einfügereihenfolge ab Durchschnittliche Tiefe: O(log2 N) Worst Case Tiefe: O(N), Aufbau: O(N2) Optimierung ähnlich wie bei Quad Trees (s. Übung) Alternative: Adaptive K-D Tree 51 Adaptiver K-D Tree: Beispiel (0,100) ’ y (5,45) DENVER (25,35) OMAHA (0,0) x’ 52 • Diskussion: - Ist nicht notwendigerweise balanciert (Übung) - Statische Datenstruktur (alle Punkte müssen vorher bekannt sein, sonst nicht sinnvoll) - Deletion ist sehr komplex - Suchen: ähnlich wie bei K- D Trees (80,65) BUFFALO (35,40) CHICAGO (50,10) Mobile 50 Adaptive K-D Trees (100,100) (60,75) TORONTO (100,0) - Wie K-D Trees, ausser, dass die Aufteilung zwischen (statt an) den Datenpunkten gemacht wird - Datenpunkte werden nur in den Blättern gespeichert - Jeder innere Knoten enthält den Median der Menge der noch übrigen, in diesem Teil befindlichen Knoten (bzgl. einem Schlüssel) - Aufteilung nicht mehr abwechselnd nach Schlüsseln, sondern nach dem Schlüssel, der noch die größte Differenz zwischen min und max besitzt. • Analyse: - (80,65) BUFFALO (85,15) ATLANTA (90,5) MIAMI (100,0) 53 54 9 K-D Trees: Deletion K-D Trees: Deletion • Diskussion (k=2): • Kandidaten für Ersatzknoten: - Deletion ist nicht so leicht wie bei binären Suchbäumen - Problem: nach Entfernung von Knoten aus Baum stimmen die Diskriminatoren nicht mehr (z.B. 2 Mal x-Koordinaten hintereinander) • Idee: Rekursiv: - DELETION(a,b) - Finde Ersatzknoten (c,d) in einem Unterbaum - Überschreibe (a,b) mit (c,d) - DELETION(c,d) - Sei (a,b) x-Diskriminator, dann: - (1) Entweder Knoten im linken Teilbaum mit größter x-Koordinate - (2) Oder Knoten im rechten Teilbaum mit kleinster x-Koordinate - (1) scheidet aus wegen Abmachung bzgl. gleicher Schlüsselwerte, denn - Annahme: sei (c,d) aus linkem Teilbaum, dann könnte ein anderer Knoten (c,z) in linkem Teilbaum existieren 55 K-D Trees: Deletion 56 K-D Trees: Beispiel Deletion (0,60) • Kandidaten für Ersatzknoten: (60,60) C(25,50) - Sei (a,b) x-Diskriminator, dann ist Kandidat: - Knoten im rechten Teilbaum von a mit kleinster x-Koordinate G(55,40) E(30,45) H(45,35) ’ • Problem: rechter Teilbaum von a ist leer • Lösung: - Finde Knoten (c,d) mit kleinster x-Koordinate in linkem Teilbaum von a - Hänge den linken Teilbaum von (a,b) an den rechten Teilbaum von (c,d) - Rekursiver Aufruf von DELETION(c,d) B(10,30) F(30,35) I(50,30) y D(35,25) A(20,20) • Beispiel: 57 K-D Trees: Deletion • Problem reduziert auf: • Bestimme den Knoten mit kleinsten x- bzw. y-Koordinate in Teilbaum von (a,b): - Muss im linken Teilbaum eines x-Diskriminators sein - Kann im linken oder rechten Teilbaum eines y- Diskriminators sein • Analyse: - Dieser Aufwand ist O(N1-1/k) (Übung) 59 (0,0) x’ (60,0) 58 procedure KD_DELETE(P,R); /* Delete node P from the k-d tree at node R. If the root of the tree was deleted, then reset R. */ begin value pointer node P; reference pointer node R; pointer node F,N; N f KD_DELETE1(P); F f FIND_FATHER(P); if null(F) then R f N /* Reset the pointer to the root of the tree */ else SON(F,SONTYPE(P)) f N; returntoavail(P); end; 60 10 recursive pointer node procedure KD_DELETE1(P); /* Delete node P and return a pointer to the root of the resulting subtree. */ begin value pointer node P; pointer node F,R; direction D; if null (LOSON(P)) and null(HISON(P)) then return(NIL) /* P is a leaf */ else D f DISC(P); ... if null(HISON(P)) then /* Special case when HISON is empty */ begin HISON(P) f LOSON(P); LOSON(P) f NIL; end; R f FIND_D_MINIMUM(HISON(P),D); F f FIND_FATHER(R); SON(F,SONTYPE(R)) f KD_DELETE1; /* Reset the father of R */ LOSON(R) f LOSON(P); HISON(R) f HISON(P); DISC(R) f DISC(P); return(R); end; 61 K-D Trees: Bereichssuche 62 K-D Trees: Bereichssuche (0,100) • Ausgabe aller Knoten (x,y), die sich innerhalb des Gebietes mit Radius d (euklidisch) um (a,b) befinden,d.h. (a-x)2 +(b-y)2 =d2 (100,100) ’ (60,75) TORONTO y (5,45) DENVER (25,35) OMAHA 63 (80,65) BUFFALO (85,15) (35,40) ATLANTA CHICAGO (50,10) Mobile (90,5) MIAMI (0,0) x’ (88,6), d=3 (100,0) K-D Trees: Bereichssuche Diskussion K-D Trees • Analyse: • An jedem Knoten muss nur jeweils ein Schlüsselvergleich durchgeführt werden. • Speicherplatz: - Worst Case für vollständigen K- D Tree: O(k N1-1/k) (Übung) 64 - Blätter: es gibt nur maximal zwei NULL-Pointer - Benötigter Speicherplatz pro innerer Knoten: 1+1+1+1+k für LEFT, RIGHT, NAME, DISC + k Wörter für k Schlüssel • Adaptive K- D Trees: - Innere Knoten benötigen nur 5 Wörter • Nachteil gegenüber Quadtree: 65 - Quadtree ist eine parallele Datenstruktur (k Schlüsselvergleiche), K-D Trees nicht 66 11