Algorithmen und Datenstrukturen
|
|
- Gerburg Siegel
- vor 7 Jahren
- Abrufe
Transkript
1 4. Bäume 4.1 Grundlagen Grundbegriffe und Definitionen Bäume sind eine Struktur zur Speicherung von (meist ganzahligen) Schlüsseln. Die Schlüssel werden so gespeichert, daß sie sich in einem einfachen und effizienten Verfahren wiederfinden lassen. Neben dem Suchen sind üblicherweise das Einfügen eines neuen Knoten (mit gegebenem Schlüssel), das Entfernen eines Knoten (mit gegebenem Schlüssel), das Durchlaufen aller Knoten eines Baums in bestimmter Reihenfolge erklärte Operationen. Weitere wichtige Verfahren sind: Das Konstruieren eines Baums mit bestimmten Eigenschaften Das Aufspalten eines Baums in mehrere Teilbäme Das Zusammenfügen mehrere Bäume zu einem Baum Definitionen Eine Datenstruktur heißt "t ärer" Baum, wenn zu jedem Element höchstens t Nachfolger (t = 2,3,... ) festgelegt sind. "t" bestimmt die Ordnung des Baumes (z.b. "t = 2": Binärbaum, "t = 3": Ternärbaum). Die Elemente eines Baumes sind die Knoten (K), die Verbindungen zwischen den Knoten sind die Kanten (R). Sie geben die Beziehung (Relation) zwischen den Knotenelementen an. Eine Datenstruktur D = (K,R) ist ein Baum, wenn R aus einer Beziehung besteht, die die folgenden 3 Bedingungen erfült: 1. Es gibt genau einen Ausgangsknoten (, das ist die Wurzel des Baums). 2. Jeder Knoten (mit Ausnahme der Wurzel) hat genau einen Vorgänger 3. Der Weg von der Wurzel zu jedem Knoten ist ein Pfad, d.h.: Für jeden von der Wurzel verschiedenen Knoten gibt es genau eine Folge von Knoten k 1, k 2,..., k n (n >= 2), bei der k i der Nachfolger von k i 1 ist. Die größte vorkommende Pfadlänge ist die Höhe eines Baums. Knoten, die keinen Nachfolger haben, sind die Blätter. Knoten mit weniger als t Nachfolger sind die Randknoten. Blätter gehören deshalb mit zum Rand. Haben alle Blattknoten eines vollständigen Baums die gleiche Pfadlänge, so heißt der Baum voll. Quasivoller Baum: Die Pfadlängen der Randknoten unterscheiden sich höchstens um 1. Bei ihm ist nur die unterste Schicht nicht voll besetzt. Linksvoller Baum: Blätter auf der untersten Schicht sind linksbündig dicht. Geordneter Baum: Ein Baum der Ordnung t ist geordnet, wenn für jeden Nachfolger k von k festgelegt ist, ob k der 1., 2.,..., t. Nachfolger von k ist. Dabei handelt es sich um eine Teilordnung, die jeweils die Söhne eines Knoten vollständig ordnet. 1
2 Speicherung von Bäumen Im allg. wird die der Baumstruktur zugrundeliegende Relation gekettet gespeichert, d.h.: Jeder Knoten zeigt über einen sog. Relationenteil (mit t Komponenten) auf seine Nachfolger. Die Verwendung eines Anfangszeigers (, der auf die Wurzel des Baums zeigt,) ist zweckmäßig Darstellung von Bäumen In der Regel erfolgt eine grafische Darstellung: Ein Nachfolgerknoten k von k wird unterhalb des Knoten k gezeichnet. Bei der Verbindung der Knotenelemente reicht deshalb eine ungerichte Linie (Kante). Bei geordneten Bäumen werden die Nachfolger eines Knoten k in der Reihenfolge "1. Nachfolger", "2. Nachfolger",... von links nach rechts angeordnet. Ein Baum ist demnach ein gerichteter Graf mit der speziellen Eigenschaft: Jeder Knoten (Sohnknoten) hat bis auf einen (Wurzelknoten) genau einen Vorgänger (Vaterknoten). 2
3 Ebene 1 linker Teilbaum von k k Ebene 2 Ebene 3 Weg, Pfad Ebene 4 Randknoten oder Blätter Abb : Berechnungsgrundlagen Die Zahl der Knoten in einem Baum ist N. Ein voller Baum der Höhe h enthält: (1) h 1 i = 1 i N = t = h t 1 t 1 h Bspw. enthält ein Binärbaum N = 2 1 Knoten. Das ergibt für den Binärbaum der Höhe 3 sieben Knoten. Unter der Pfadsumme Z versteht man die Anzahl der Knoten, die auf den unterschiedlichen Pfaden im vollen t ären Baum auftreten können: (2) h 1 i= 1 Z = i t i Die Summe kann durch folgende Formel ersetzt werden: 3
4 Z h t h h t = t 1 1 ( t 1) 2 t und h können aus (1) bestimmt werden: t h = N ( t 1) + 1 h = log ( N ( t 1) + 1) t Mit Gleichung (1) ergibt sich somit für Z Z = log t ( N ( t 1) + 1) ( N ( t 1) + 1) N ( t 1) 2 t 1 ( t 1) = ( N ( t 1) + 1) log t ( N ( t 1) + 1) N t 1 Für t = 2 ergibt sich damit: h h Z = h 2 ( 2 1) bzw. Z = ( N + 1) ld( N + 1) N Die mittlere Pfadlänge ist dann: (3) Z ( N ( t 1) + 1) log t ( N ( t 1) + 1) N ( N ( t 1) + 1) log t ( N ( t 1) + 1) 1 Zmit = = = N N ( t 1) N ( t 1) t 1 Für t = 2 ist Z Z mit = = (4) N N + 1 ld( N + 1) 1 N Die Formeln unter (3) und (4) ergeben den mittleren Suchaufwand bei gleichhäufigem Aufsuchen der Elemente. Ist dies nicht der Fall, so ordnet man den Elementen die relativen Gewichte g i (i = 1, 2, 3,..., N) bzw. die Aufsuchwahrscheinlichkeiten zu: p i = gi G, G = N i= 1 g i Zg = gi hi Man kann eine gewichtete Pfadsumme i= 1 bzw. einen mitlleren Z N g ( Z g ) mit = = pi hi Suchaufwand G i = 1 berechnen. N 4
5 4.1.4 Klassifizierung von Bäumen Wegen der großen Bedeutung, die binäre Bäume besitzen, ist es zweckmäßig in Binär und t äre Bäume zu unterteilen. Bäume werden oft verwendet, um eine Menge von Daten festzulegen, deren Elemente nach einem Schlüssel wiederzufinden sind (Suchbäume). Die Art, nach der beim Suchen in den Baumknoten eine Auswahl unter den Nachfolgern getroffen wird, ergibt ein weiteres Unterscheidungsmerkmal für Bäume. Intervallbäume In den Knoten eines Baumes befinden sich Daten, mit denen immer feinere Teilintervalle ausgesondert werden. Bsp.: Binärer Suchbaum Die Schlüssel sind nach folgendem System angeordnet. Neu ankommende Elemente werden nach der Regel "falls kleiner" nach links bzw. "falls größer" nach rechts abgelegt Es kann dann leicht festgestellt werden, in welchem Teilbereich ein Schlüsselwort vorkommt. Selektorbäume (Entscheidungsbäume) Der Suchweg ist hier durch eine Reihe von Eigenschaften bestimmt. Beim Binärbaum ist das bspw. eine Folge von 2 Entscheidungsmöglichkeiten. Solche Entscheidungsmöglichkeiten können folgendermaßen codiert sein: 0 : Entscheidung für den linken Nachfolger 1 : Entscheidung für den rechten Nachfolger Die Folge von Entscheidungen gibt dann ein binäres Codewort an. Dieses Codewort kann mit einem Schlüssel bzw. mit einem Schlüsselteil übereinstimmen. Bsp.: "Knotenorientierter binärer Selektorbaum" Folgende Schlüsselfolge wird zum Erstellen des Baums herangezogen: 5
6 17 10 = = = = = = = = = Der zugehörige Binärbaum besitzt dann folgende Gestalt: _ 38 1_ 39 01_ 32 10_ 63 11_ 101_ _ _ In den Knoten dient demnach der Wertebereich einer Teileigenschaft zur Auswahl der nächsten Untergruppe. Knotenorientierte und blattorientierte Bäume Zur Unterscheidung von Bäumen kann auf die Aufbewahrungsstelle der Daten zurückgegriffen werden: 1. Knotenorientierte Bäume Daten befinden sich hier in allen Baumknoten 2. Blattorientierte Bäume Daten befinden sich nur in den Blattknoten Optimierte Bäume Man unterscheidet statisch und dynamisch optimierte Bäume. In beiden Fällen sollen entartete Bäume (schiefe Bäume, Äste werden zu linearen Listen) vermieden werden. Statische Optimierung bedeutet: Der Baum wird neu (oder wieder neu) aufgebaut. Optimalität ist auf die Suchoperation bezogen. Es interessiert dabei das Aussehen des Baums, wenn dieser vor Gebrauch optimiert werden kann. Bei der dynamischen Optimierung wird der Baum während des Betriebs (bei jedem Ein und Ausfügen) optimiert. Ziel ist also hier: Eine günstige Speicherstruktur 6
7 zu erhalten. Diese Aufgabe kann im allg. nicht vollständig gelöst werden, eine Teiloptimierung (lokale Optimierung) reicht häufig aus. Werden die Operationen "Einfügen", "Löschen" und "Suchen" ohne besondere Einschränkungen oder Zusätze angewendet, so spricht man von freien Bäumen. Strukturbäume Sie dienen zur Darstellung und Speicherung hierarchischer Zusammenhänge. Bsp.: "Darstellung eines arithmetischen Ausdrucks" Operationen in einem arithmetischen Ausdruck sind zweiwertig (, die einwertige Operation "Minus" kann als Vorzeichen dem Operanden direkt zugeordnet werden). Zu jeder Operation gehören demnach 2 Operanden. Somit bietet sich die Verwendung eines binären Baumes an. Für den arithmetischen Ausdruck ( A + B / C) ( D E F) ergibt sich dann folgende Baumdarstellung: * + A / D * B C E F 7
8 4.2 Freie Binäre Intervallbäume Ordnungsrelation und Darstellung Freie Bäume sind durch folgende Ordnungsrelation bestimmt: In jedem Knoten eines knotenorientierten, geordneten Binärbaums gilt: Alle Schlüssel im rechten (linken) Unterbaum sind größer (kleiner) als der Schlüssel im Knoten selbst. Mit Hilfe dieser Ordnungsrelation erstellte Bäume dienen zum Zugriff auf Datenbestände (Aufsuchen eines Datenelements). Die Daten sind die Knoten (Datensätze, segmente, elemente). Die Kanten des Zugriffsbaums sind Zeiger auf weitere Datenknoten (Nachfolger). Dateninformation Knotenzeiger Schluessel LINKS Datenteil RECHTS Zeiger zum linken Sohn Zeiger zum rechten Sohn Das Aufsuchen eines Elements im Zugriffsbaum geht vom Wurzelknoten über einen Kantenzug (d.i. eine Reihe von Zwischenknoten) zum gesuchten Datenelement. Bei jedem Zwischenknoten auf diesem Kantenzug findet ein Entscheidungsprozeß über die folgenden Vergleiche statt: 1. Die beiden Schlüssel sind gleich: Das Element ist damit gefunden 2. Der gesuchte Schlüssel ist kleiner: Das gesuchte Element kann sich dann nur im linken Unterbaum befinden 3. Der gesuchte Schlüssel ist größer: Das gesuchte Element kann sich nur im rechten Unterbaum befinden. Das Verfahren wird solange wiederholt, bis das gesuchte (Schlüssel ) Element gefunden ist bzw. feststeht, daß es in dem vorliegenden Datenbestand nicht vorhanden ist. Struktur und Wachstum binärer Bäume sind durch die Ordnungsrelation bestimmt: Aufgabe: Betrachte die 3 Schlüssel 1, 2, 3. Diese 3 Schlüssel können durch verschieden angeordnete Folgen bei der Eingabe unterschiedliche binäre Bäume erzeugen. Stellen Sie alle Bäume, die aus unterschiedlichen Eingaben der 3 Schlüssel resultieren, dar! 8
9 1, 2, 3 1, 3, 2 2, 1, , 3, 1 3, 1, 2 3, 2, Es gibt also: Sechs unterschiedliche Eingabefolgen und somit 6 unterschiedliche Bäume. Allgemein können n Elemente zu n! verschiedenen Anordnungen zusammengestellt werden. Suchaufwand Der mittlere Suchaufwand für einen vollen Baum beträgt Z mit = N + 1 N ld ( N + 1) 1 Zur Bestimmung des Suchaufwands stellt man sich vor, daß ein Baum aus dem leeren Baum durch sukzessives Einfuegen der N Schlüssel entstanden ist. Daraus resultieren N! Permutationen der N Schlüssel. Über all diese Baumstrukturen ist der Mittelwert zu bilden, um schließlich den Suchaufwand festlegen zu können. Aus den Schlüsselwerten 1, 2,..., N interessiert zunächst das Element k, das die Wurzel bildet. k Hier gibt es: (k 1)! Unterbäume Schlüsseln 1..N Hier gibt es: (N k)! Unterbäume mit den Schlüsseln k+1,..., N 9
10 Der mittlere Suchaufwand im gesamten Baum ist: Z 1 = ( N N + Z k + Z N k 1 ( 1) ( )) N k N k Z k 1: mittlerer Suchaufwand im linken Unterbaum Z N k: mittlerer Suchaufwand im rechten Unterbaum Zusätzlich zu diesen Aufwendungen entsteht ein Aufwand für das Einfügen der beiden Teilbäume an die Wurzel. Das geschieht (N 1) mal. Zusammen mit dem dem Suchschritt selbst ergibt das N mal. Der angegebene Suchaufwand gilt nur für die Wurzel mit dem Schlüssel k. Da alle Werte für k gleichwahrscheinlich sind, gilt allgemein: Z ( k) N N 1 = ( N + Zk ( k ) + ZN k ( N k)) N k = 1 bzw. Z N N 2 = 1+ Zk k N ( ( ) k = 1 N 1 2 ZN 1 = 1+ Zk k 2 bzw. für N 1: N ( 1 ( 1) ( 1) k= 1 N N ZN Z N 1 = Zk k Zk k 2 N 1 ( 1) 2 N 1 ( 1) ( 1) k= 1 k 1 Es läßt sich daraus ableiten: N Z N NN Z N N N + = N ( N + 1) N YN = ZN Mit der Ersatzfunktion N + 1 folgt die Rekursionsformel: N N 2 N 1 2 i 1 1 N YN = YN 1 + YN = N ( N + 1) = 2 3 bzw. nach Auflösung i ( i + 1) i N Einsetzen ergibt: Z + 1 NN HS N + 1 = 2 3 = 2 ( HS + 1 1) 1 N N N N i= 1 i = 1 "HS" ist die harmonische Summe: HS N N = 1 N i= 1 Sie läßt sich näherungsweise mit ln( N) (ln( N)) = ld( N). Damit ergibt sich schließlich: Z ld N mit = 14. ( + 1) 2 Darstellung Jeder geordnete binäre Baum ist eindeutig durch folgende Angaben bestimmt: 1 vgl. Wettstein, H.: Systemprogrammierung, 2. Auflage, S
11 1. Angabe der Wurzel 2. Für jede Kante Angabe des linken Teilbaums ( falls vorhanden) sowie des rechten Teilbaums (falls vorhanden) Die Angabe für die Verzweigungen befinden sich in den Baumknoten, die die zentrale Konstruktionseinheit für den Aufbau binärerer Bäume sind. 1. Die Klassenschablone "Baumknoten" in C++ 2 // Schnittstellenbeschreibung // Die Klasse binaerer Suchbaum binsbaum benutzt die Klasse baumknoten template <class T> class binsbaum; // Deklaration eines Binaerbaumknotens fuer einen binaeren Baum template <class T> class baumknoten protected: // zeigt auf die linken und rechten Nachfolger des Knoten baumknoten<t> *links; baumknoten<t> *rechts; public: // Das oeffentlich zugaenglich Datenelement "daten" T daten; // Konstruktor baumknoten (const T& merkmal, baumknoten<t> *lzgr = NULL, baumknoten<t> *rzgr = NULL); // virtueller Destruktor virtual ~baumknoten(void); // Zugriffsmethoden auf Zeigerfelder baumknoten<t>* holelinks(void) const; baumknoten<t>* holerechts(void) const; // Die Klasse binsbaum benoetigt den Zugriff auf // "links" und "rechts" friend class binsbaum<t>; ; // Schnittstellenfunktionen // Konstruktor: Initialisiert "daten" und die Zeigerfelder // Der Zeiger NULL verweist auf einen leeren Baum template <class T> baumknoten<t>::baumknoten (const T& merkmal, baumknoten<t> *lzgr, baumknoten<t> *rzgr): daten(merkmal), links(lzgr), rechts(rzgr) // Die Methode holelinks ermoeglicht den Zugriff auf den linken // Nachfolger template <class T> baumknoten<t>* baumknoten<t>::holelinks(void) const // Rueckgabe des Werts vom privaten Datenelement links return links; // Die Methode "holerechts" erlaubt dem Benutzer den Zugriff auf den // rechten Nachfoger template <class T> baumknoten<t>* baumknoten<t>::holerechts(void) const // Rueckgabe des Werts vom privaten Datenelement rechts return rechts; // Destruktor: tut eigentlich nichts template <class T> baumknoten<t>::~baumknoten(void) 2. Baumknotendarstellung in Java 2 vgl. baumkno.h 11
12 import java.util.*; // Elementarer Knoten eines binaeren Baums, der nicht ausgeglichen ist // Der Zugriff auf diese Klasse ist nur innerhalb eines Verzeichnisses // bzw. Pakets moeglich class BinaerBaumknoten // Instanzvariable protected BinaerBaumknoten links; protected BinaerBaumknoten rechts; public Comparable daten; // linker Teilbaum // rechter Teilbaum // Dateninhalt der Knoten // Konstruktor public BinaerBaumknoten(Comparable datenelement) this(datenelement, null, null ); public BinaerBaumknoten(Comparable datenelement, BinaerBaumknoten l, BinaerBaumknoten r) daten = datenelement; links = l; rechts = r; public BinaerBaumknoten getlinks() return links; public BinaerBaumknoten getrechts() return rechts; Operationen 1. Generieren eines Suchbaums Bsp.: Gestalt des durch die Prozedur ERSTBAUM erstellten Binärbaums nach der Eingabe der Schlüsselfolge (12, 7, 15, 5, 8, 13, 2, 6, 14). 12
13 Schlüssel LINKS 12 RECHTS a) Erzeugen eines Binärbaumknotens bzw. eines binären Baums in C++ Zum Erzeugen eines Binärbaumknotens kann folgende Funktionsschablone herangezogen werden: template <class T> baumknoten<t>* erzeugebaumknoten(t merkmal, baumknoten<t>* lzgr = NULL, baumknoten<t>* rzgr = NULL) baumknoten<t> *z; // Erzeugen eines neuen Knoten z = new baumknoten<t>(merkmal,lzgr,rzgr); if (z == NULL) cerr << "Kein Speicherplatz!\n"; exit(1); return z; // Rueckgabe des Zeigers Der durch den Baumknoten belegte Speicherplatz kann über folgende Funktionsschablone freigegeben werden: template <class T> void gibknotenfrei(baumknoten<t>* z) delete z; Der folgende Hauptprogrammabschnitt erzeugt einen binären Baum folgende Gestalt: 13
14 A B C D E Abb:: void main(void) baumknoten<char> *a, *b, *c, *d, *e; d = new baumknoten<char>( D ); e = new baumknoten<char>( E ); b = new baumknoten<char>( B,NULL,d); c = new baumknoten<char>( C,e); a = new baumknoten<char>( A,b,c); 14
15 b) Erzeugen eines Binärbaumknotens bzw. eines binären Baums in Java class StringBinaerBaumknoten private String sk; protected StringBinaerBaumknoten links, rechts; public StringBinaerBaumknoten (String s) links = rechts = null; sk = s; public void insert (String s) // Fuege s korrekt ein. if (s.compareto(sk) > 0) // dann rechts if (rechts==null) rechts = new StringBinaerBaumknoten(s); else rechts.insert(s); else // sonst links if (links==null) links=new StringBinaerBaumknoten(s); else links.insert(s); public String getstring () return sk; public StringBinaerBaumknoten getlinks () return links; public StringBinaerBaumknoten getrechts () return rechts; public class TestStringBinaerBaumKnoten public static void main (String args[]) StringBinaerBaumknoten baum=null; for (int i = 0; i < 20; i++) // 20 Zusfallsstrings speichern String s = "Zufallszahl " + (int)(math.random() * 100); if (baum == null) baum = new StringBinaerBaumknoten(s); else baum.insert(s); print(baum); // Sortiert wieder ausdrucken public static void print (StringBinaerBaumknoten baum) // Rekursive Druckfunktion if (baum == null) return; print(baum.getlinks()); System.out.println(baum.getString()); print(baum.getrechts()); 15
16 2. Suchen und Einfügen Vorstellung zur Lösung: 1. Suche nach dem Schlüsselwert 2. Falls vorhanden kein Einfügen 3. Bei erfolgloser Suche Einfügen als Sohn des erreichten Blatts a) Implementierung in C++ Das "Einfügen" 3 ist eine Methode in der Klassenschablone für einen binären Suchbaum binsbaum. Zweckmäßigerweise stellt diese Klasse Datenelemente unter protected zur Verfügung. #include "baumkno.h" // Schnittstellenbeschreibung template <class T> class binsbaum protected: // Zeiger auf den Wurzelknoten und den Knoten, auf den am // haeufigsten zugegriffen wird baumknoten<t> *wurzel; baumknoten<t> *aktuell; // Anzahl Knoten im Baum int groesse; // Speicherzuweisung / Speicherfreigabe // Zuweisen eines neuen Baumknoten mit Rueckgabe // des zugehoerigen Zeigerwerts baumknoten<t> *holebaumknoten(const T& merkmal, baumknoten<t> *lzgr,baumknoten<t> *rzgr) baumknoten<t> *z; // Datenfeld ubd die beiden Zeiger werden initialisiert z = new baumknoten<t> (merkmal, lzgr, rzgr); if (z == NULL) cerr << "Speicherbelegungsfehler!\n"; exit(1); return z; // gib den Speicherplatz frei, der von einem Baumknoten belegt wird void freigabeknoten(baumknoten<t> *z) // wird vom Kopierkonstruktor und Zuweisungsoperator benutzt delete z; // Kopiere Baum b und speichere ihn im aktuellen Objekt ab baumknoten<t> *kopierebaum(baumknoten<t> *b) // wird vom Destruktor, Zuweisungsoperator und bereinigeliste benutzt baumknoten<t> *neulzgr, *neurzgr, *neuerknoten; // Falls der Baum leer ist, Rueckgabe von NULL if (b == NULL) return NULL; // Kopiere den linken Zweig von der Baumwurzel b und weise seine // Wurzel neulzgr zu if (b >links!= NULL) neulzgr = kopierebaum(b >links); else neulzgr = NULL; // Kopiere den rechten Zweig von der Baumwurzel b und weise seine // Wurzel neurzgr zu if (b >rechts!= NULL) neurzgr = kopierebaum(b >rechts); else neurzgr = NULL; // Weise Speicherplatz fuer den aktuellen Knoten zu und weise seinen // Datenelementen Wert und Zeiger seiner Teilbaeume zu neuerknoten = holebaumknoten(b >daten, neulzgr, neurzgr); return neuerknoten; 3 vgl. bsbaum.h 16
17 // Loesche den Baum, der durch im aktuellen Objekt gespeichert ist void loeschebaum(baumknoten<t> *b) // Lokalisiere einen Knoten mit dem Datenelementwert von merkmal // und seinen Vorgaenger (eltern) im Baum // falls der aktuelle Wurzelknoten nicht NULL ist, loesche seinen // linken Teilbaum, seinen rechten Teilbaum und dann den Knoten selbst if (b!= NULL) loeschebaum(b >links); loeschebaum(b >rechts); freigabeknoten(b); // Suche nach dem Datum "merkmal" im Baum. Falls gefunden, Rueckgabe // der zugehoerigen Knotenadresse; andernfalls NULL baumknoten<t> *findeknoten(const T& merkmal, baumknoten<t>* & eltern) const // Durchlaufe b. Startpunkt ist die Wurzel baumknoten<t> *b = wurzel; // Die "eltern" der Wurzel sind NULL eltern = NULL; // Terminiere bei einen leeren Teilbaum while(b!= NULL) // Halt, wenn es passt if (merkmal == b >daten) break; else // aktualisiere den "eltern" Zeiger und gehe nach rechts // bzw. nach links eltern = b; if (merkmal < b >daten) b = b >links; else b = b >rechts; // Rueckgabe des Zeigers auf den Knoten; NULL, falls nicht gefunden return b; public: // Konstruktoren, Destruktoren binsbaum(void); binsbaum(const binsbaum<t>& baum); ~binsbaum(void); // Zuweisungsoperator binsbaum<t>& operator= (const binsbaum<t>& rs); // Bearbeitungsmethoden int finden(t& merkmal); void einfuegen(const T& merkmal); void loeschen(const T& merkmal); void bereinigeliste(void); int leererbaum(void) const; int baumgroesse(void) const; // baumspezifische Methoden void aktualisieren(const T& merkmal); baumknoten<t> *holewurzel(void) const; ; Die Schnittstellenfunktion void einfuegen(const T& merkmal); besitzt folgende Definition 4 : // Einfuegen "merkmal" in den Suchbaum template <class T> void binsbaum<t>::einfuegen(const T& merkmal) // b ist der aktuelle Knoten beim Durchlaufen des Baums baumknoten<t> *b = wurzel, *eltern = NULL, *neuerknoten; // Terminiere beim leeren Teilbaum while(b!= NULL) // Aktualisiere den zeiger "eltern", // dann verzweige nach links oder rechts 4 vgl. bsbaum.h 17
18 eltern = b; if (merkmal < b >daten) b = b >links; else b = b >rechts; // Erzeuge den neuen Blattknoten neuerknoten = holebaumknoten(merkmal,null,null); // Falls "eltern" auf NULL zeigt, einfuegen eines Wurzelknoten if (eltern == NULL) wurzel = neuerknoten; // Falls merkmal < eltern >daten, einfuegen als linker Nachfolger else if (merkmal < eltern >daten) eltern >links = neuerknoten; else // Falls merkmal >= eltern >daten, einfuegen als rechter Nachf. eltern >rechts = neuerknoten; // Zuweisen "aktuell": "aktuell" ist die Adresse des neuen Knoten aktuell = neuerknoten; groesse++; b) Eine generische Klasse für den binären Suchbaum in Java 5 Der binäre Suchbaum setzt voraus, dass alle Datenelemente in eine Ordnungsbeziehung 6 gebracht werden können. Eine generische Klasse für einen binären Suchbaum erfordert daher ein Interface, das Ordnungsbeziehungen zwischen Daten eines Datenbestands festlegt. Diese Eigenschaft besitzt das Interface Comparable: public interface Comparable int compareto(comparable rs) Das Interface 7 zeigt, dass zwei Datenelemente über die Methode "compareto" verglichen werden können. Über die Defintion eines Interface wird auch der zugehörige Referenztyp erzeugt, der wie andere Datentypen eingesetzt werden kann. // Freier binaerer Intervallbaum // Generische Klasse fuer einen unausgeglichenen binaeren Suchbaum // // Konstruktor: Initialisierung der Wurzel mit dem Wert null // // ************ oeffentlich zugaengliche Methoden******************** // void insert( x ) > Fuege x ein // void remove( x ) > Entferne x // Comparable find( x ) > Gib das Element zurueck, das zu x passt // Comparable findmin( ) > Rueckgabe des kleinsten Elements // Comparable findmax( ) > Rueckgabe des groessten Elements // boolean isempty( ) > Return true if empty; else false // void makeempty( ) > Entferne alles // void printtree( ) > Ausgabe der Binaerbaum Elemente in sortierter // Folge // void ausgbinaerbaum() > Ausgabe der Binaerbaum Elemente um 90 Grad // vers. 5 vgl. pr vgl. Kapitel 1, Java Interfaces werden in der Regel als eine Form abstrakter Klassen beschrieben, durch die einzelne Klassen der Hierarchie zusätzliche Funktionalität erhalten können. Sollen die Klassen diese Funktionalität durch Vererbung erhalten, müssten sie in einer gemeinsamen Superklasse angesiedelt werden. Weil ein Interface keine Implementierung enthält, kann auch keine Instanz davon erzeugt werden. Eine Klasse, die nicht alle Methoden eines Interface implementiert, wird zu einer abstrakten Klasse. 18
19 * Implementiert einen unausgeglichenen binaeren Suchbaum. * Das Einordnen in den Suchbaum basiert auf der Methode compareto public class BinaererSuchbaum // Private Datenelemente Die Wurzel des Baums private BinaerBaumknoten root = null; Container mit daten zum Erstellen eines Baums Vector einvector; // Oeffentlich zugaengliche Methoden * Konstruktoren public BinaererSuchbaum() root = null; public BinaererSuchbaum(Vector einvector) this.einvector = einvector; for (int i = 0; i < einvector.size();i++) insert((comparable) einvector.elementat(i)); * Einfuegen eines Elements in den binaeren Suchbaum * Duplikate werden ignoriert public BinaerBaumknoten getroot() return root; public void insert( Comparable x ) root = insert(x, root); * Entfernen aus dem Baum. Falls x nicht da ist, geschieht nichts public void remove( Comparable x ) root = remove(x, root); * finde das kleinste Element im Baum public Comparable findmin() return elementat(findmin(root)); * finde das groesste Element im Baum public Comparable findmax() return elementat(findmax(root)); * finde ein Datenelement im Baum 19
20 public Comparable find(comparable x) return elementat(find(x, root)); * Mache den Baum leer public void makeempty() root = null; * Test, ob der Baum leer ist public boolean isempty() return root == null; * Ausgabe der Datenelemente in sortierter Reihenfolge public void printtree() if( isempty( ) ) System.out.println( "Baum ist leer" ); else printtree( root ); * Ausgabe der Elemente des binaeren Baums um 90 Grad versetzt public void ausgbinaerbaum() if( isempty() ) System.out.println( "Leerer baum" ); else ausgbinaerbaum( root,0 ); // Private Methoden * Methode fuer den Zugriff auf ein Datenelement private Comparable elementat( BinaerBaumknoten b ) return b == null? null : b.daten; * Interne Methode fuer das Einfuegen in einen Teilbaum private BinaerBaumknoten insert(comparable x, BinaerBaumknoten b) 1 if( b == null ) 2 b = new BinaerBaumknoten( x, null, null ); 3 else if( x.compareto( b.daten ) < 0 ) 4 b.links = insert( x, b.links ); 5 else if( x.compareto( b.daten ) > 0 ) 6 b.rechts = insert( x, b.rechts ); 7 else 8 ; // Duplikat; tue nichts 9 return b; * Interne Methode fuer das Entfernen eines Knoten in einem Teilbaum 20
21 private BinaerBaumknoten remove(comparable x, BinaerBaumknoten b) if( b == null ) return b; // nichts gefunden; tue nichts if( x.compareto(b.daten) < 0 ) b.links = remove(x, b.links ); else if( x.compareto(b.daten) > 0 ) b.rechts = remove( x, b.rechts ); else if( b.links!= null && b.rechts!= null ) // Zwei Kinder b.daten = findmin(b.rechts).daten; b.rechts = remove(b.daten, b.rechts); else b = ( b.links!= null )? b.links : b.rechts; return b; * Interne Methode zum Bestimmen des kleinsten Datenelements im Teilbaum private BinaerBaumknoten findmin(binaerbaumknoten b) if (b == null) return null; else if( b.links == null) return b; return findmin(b.links ); * Interne Methode zum Bestimmen des groessten Datenelements im Teilbaum private BinaerBaumknoten findmax( BinaerBaumknoten b) if( b!= null ) while( b.rechts!= null ) b = b.rechts; return b; * Interne Methode zum Bestimmen eines Datenelements im Teilbaum. private BinaerBaumknoten find(comparable x, BinaerBaumknoten b) if(b == null) return null; if( x.compareto(b.daten ) < 0) return find(x, b.links); else if( x.compareto(b.daten) > 0) return find(x, b.rechts); else return b; // Gefunden! * Internae Methode zur Ausgabe eines Teilbaums in sortierter Reihenfolge private void printtree(binaerbaumknoten b) if(b!= null) printtree(b.links); System.out.print(b.daten); System.out.print( ); 21
22 printtree( b.rechts ); * Ausgabe des Binaerbaums um 90 Grad versetzt private void ausgbinaerbaum(binaerbaumknoten b, int stufe) if (b!= null) ausgbinaerbaum(b.links, stufe + 1); for (int i = 0; i < stufe; i++) System.out.print( ); System.out.println(b.daten); ausgbinaerbaum(b.rechts, stufe + 1); 3. Löschen eines Knoten Es soll ein Knoten mit einem bestimmten Schlüsselwert entfernt werden. Fälle A) Der zu löschende Knoten ist ein Blatt Bsp.: vorher nachher Das Entfernen kann leicht durchgeführt werden B) Der zu löschende Knoten hat genau einen Sohn 22
23 vorher nachher C) Der zu löschende Knoten hat zwei Söhne vorher nachher Der Knoten k wird durch den linken Sohn ersetzt. Der rechte Sohn von k wird rechter Sohn der rechtesten Ecke des linken Teilbaums. Der resultierende Teilbaum T ist ein Suchbaum, häufig allerdings mit erheblich vergrößerter Höhe. Aufgaben: 1. Gegeben ist ein binärer Baum folgender Gestalt: k k1 k2 Die Wurzel wird gelöscht. Welche Gestalt nimmt der Baum dann an: k3 23
24 k1 vv k3 v k2 Es ergibt sich eine Höhendifferenz H, die durch folgende Beziehung eingegrenzt ist: 1 H H ( T L ) H( T L ) ist die Höhe des linken Teilbaums. 2. Gegeben ist die folgende Gestalt eines binären Baums Welche Gestalt nimmt dieser Baum nach dem Entfernen der Schlüssel mit den unter a) bis f) angegebenen Werten an? a) 2 b)
25 c) d) e) f) Schlüsseltransfer Der angegebene Algorithmus zum Löschen von Knoten kann zu einer beträchtlichen Vergrößerung der Baumhöhe führen. Das bedeutet auch eine beträchtliche Steigerung des mittleren Suchaufwands. Man ersetzt häufig die angegebene Verfahrensweise durch ein anderes Verfahren, das unter dem Namen Schlüsseltransfer bekannt ist. Der zu löschende Schlüssel (Knoten) wird ersetzt durch den kleinsten Schlüssel des rechten oder den größten Schlüssel des linken Teilbaums. Dieser ist dann nach Fall A) bzw. B) aus dem Baum herauszunehmen. Bsp.: 25
26 Test der Verfahrensweise "Schlüsseltransfer": 1) Der zu löschende Baumknoten besteht nur aus einem Wurzelknoten, z.b.: Schlüssel LINKS 12 RECHTS Ergebnis: Der Wurzelknoten wird gelöscht. 2) Vorgegeben ist Schlüssel LINKS 12 RECHTS Der Wurzelknoten wird gelöscht. Ergebnis: 26
27 ) Vorgegeben ist Schlüssel LINKS 12 RECHTS Der Wurzelknoten wird gelöscht. Ergebnis: 27
28 Schlüssel LINKS 13 RECHTS a) Implementierung der Verfahrenweise Schlüsseltransfer zum Löschen von Baumknoten in einem binären Suchbaum in C++ // Falls "merkmal" im Baum vorkommt, dann loesche es template <class T> void binsbaum<t>::loeschen(const T& merkmal) // LKnoZgr: Zeiger auf Knoten L, der geloescht werden soll // EKnoZgr: Zeiger auf die "eltern" E des Knoten L // ErsKnoZgr: Zeiger auf den rechten Knoten R, der L ersetzt baumknoten<t> *LKnoZgr, *EKnoZgr, *ErsKnoZgr; // Suche nach einem Knoten, der einen Knoten enthaelt mit dem // Datenwert von "merkmal". Bestimme die aktuelle Adresse diese Knotens // und die seiner "eltern" if ((LKnoZgr = findeknoten (merkmal, EKnoZgr)) == NULL) return; // Falls LKnoZgr einen NULL Zeiger hat, ist der Ersatzknoten // auf der anderen Seite des Zweigs if (LKnoZgr >rechts == NULL) ErsKnoZgr = LKnoZgr >links; else if (LKnoZgr >links == NULL) ErsKnoZgr = LKnoZgr >rechts; // Beide Zeiger von LKnoZgr sind nicht NULL else // Finde und kette den Ersatzknoten fuer LKnoZgr aus. // Beginne am linkten Zweig des Knoten LKnoZgr, // bestimme den Knoten, dessen Datenwert am groessten // im linken Zweig von LKnoZgr ist. Kette diesen Knoten aus. // EvonErsKnoZgr: Zeiger auf die "eltern" des zu ersetzenden Knoten baumknoten<t> *EvonErsKnoZgr = LKnoZgr; // erstes moegliches Ersatzstueck: linker Nachfolger von L ErsKnoZgr = LKnoZgr >links; // steige den rechten Teilbaum des linken Nachfolgers von LKnoZgr hinab, // sichere den Satz des aktuellen Knoten und den seiner "Eltern" // Beim Halt, wurde der zu ersetzende Knoten gefunden while(ersknozgr >rechts!= NULL) EvonErsKnoZgr = ErsKnoZgr; ErsKnoZgr = ErsKnoZgr >rechts; if (EvonErsKnoZgr == LKnoZgr) // Der linke Nachfolger des zu loeschenden Knoten ist das // Ersatzstueck // Zuweisung des rechten Teilbaums ErsKnoZgr >rechts = LKnoZgr >rechts; else // es wurde sich um mindestens einen Knoten nach unten bewegt // der zu ersetzende Knoten wird durch Zuweisung seines // linken Nachfolgers zu "Eltern" geloescht 28
29 EvonErsKnoZgr >rechts = ErsKnoZgr >links; // plaziere den Ersatzknoten an die Stelle von LKnoZgr ErsKnoZgr >links = LKnoZgr >links; ErsKnoZgr >rechts = LKnoZgr >rechts; // Vervollstaendige die Verkettung mit den "Eltern" Knoten // Loesche den Wurzelknoten, bestimme eine neue Wurzel if (EKnoZgr == NULL) wurzel = ErsKnoZgr; // Zuweisen Ers zum korrekten Zweig von E else if (LKnoZgr >daten < EKnoZgr >daten) EKnoZgr >links = ErsKnoZgr; Else EKnoZgr >rechts = ErsKnoZgr; // Loesche den Knoten aus dem Speicher und erniedrige "groesse" freigabeknoten(lknozgr); groesse ; b) Implementierung der Verfahrenweise Schlüsseltransfer zum Löschen von Baumknoten in einem binären Suchbaum in Java * Interne Methode fuer das Entfernen eines Knoten in einem Teilbaum private BinaerBaumknoten remove(comparable x, BinaerBaumknoten b) if( b == null ) return b; // nichts gefunden; tue nichts if( x.compareto(b.daten) < 0 ) b.links = remove(x, b.links ); else if( x.compareto(b.daten) > 0 ) b.rechts = remove( x, b.rechts ); else if( b.links!= null && b.rechts!= null ) // Zwei Kinder b.daten = findmin(b.rechts).daten; b.rechts = remove(b.daten, b.rechts); else b = ( b.links!= null )? b.links : b.rechts; return b; 29
30 4.2.3 Ordnungen und Durchlaufprinzipien Das Prinzip, wie ein geordneter Baum durchlaufen wird, legt eine Ordnung auf der Menge der Knoten fest. Es gibt 3 Möglichkeiten (Prinzipien), die Knoten eines binären Baums zu durchlaufen: 1. Inordnungen LWR Ordnung (1) Durchlaufen (Aufsuchen) des linken Teilbaums in INORDER (2) Aufsuchen der BAUMWURZEL (3) Durchlaufen (Aufsuchen) des rechten Teilbaums in INORDER RWL Ordnung (1) Durchlaufen (Aufsuchen) des rechten Teilbaums in INORDER (2) Aufsuchen der BAUMWURZEL (3) Durchlaufen (Aufsuchen) des Teilbaums in INORDER Der LWR Ordnung und die RWL Ordnung sind zueinander invers. Die LWR Ordnung heißt auch symmetrische Ordnung. 2. Präordnungen WLR Ordnung (1) Aufsuchen der BAUMWURZEL (2) Durchlaufen (Aufsuchen) des linken Teilbaums in PREORDER (3) Durchlaufen (Aufsuchen) des rechten Teilbaums in PREORDER WRL Ordnung (1) Aufsuchen der BAUMWURZEL (2) Durchlaufen (Aufsuchen) des rechten Teilbaums in PREORDER (3) Durchlaufen (Aufsuchen) des linken Teilbaums in PREORDER Es wird hier grundsätzlich die Wurzel vor den (beiden) Teilbäumen durchlaufen. 3. Postordnungen LRW Ordnung (1) Durchlaufen (Aufsuchen) des linken Teilbaums in POSTORDER (2) Durchlaufen (Aufsuchen) des rechten Teilbaums in POSTORDER (3) Aufsuchen der BAUMWURZEL Zunächst werden die beiden Teilbäume und dann die Wurzel durchlaufen. RLW Ordnung (1) Durchlauden (Aufsuchen) des rechten Teilbaums in POSTORDER (2) Durchlaufen (Aufsuchen) des linken Teilbaums in POSTORDER (3) Aufsuchen der BAUMWURZEL Zunächst werden die beiden Teilbäume und dann die Wurzel durchlaufen. 30
31 a) Funktionsschablonen für das Durchlaufen binärer Bäume in C++ // Funktionsschablonen fuer Baumdurchlaeufe template <class T> void inorder(baumknoten<t>* b, void aufsuchen(t& merkmal)) if (b!= NULL) inorder(b >holelinks(),aufsuchen); aufsuchen(b >daten); inorder(b >holerechts(),aufsuchen); template <class T> void postorder(baumknoten<t>* b, void aufsuchen(t& merkmal)) if (b!= NULL) postorder(b >holelinks(),aufsuchen); // linker Abstieg postorder(b >holerechts(),aufsuchen); aufsuchen(b >daten); // rechter Abstieg b) Rekursive Ausgabefunktion in Java 8 public static void print (StringBinaerBaumknoten baum) // Rekursive Druckfunktion if (baum == null) return; print(baum.getlinks()); System.out.println(baum.getString()); print(baum.getrechts()); Aufgaben: Gegeben sind eine Reihe binärer Bäume. Welche Folgen entstehen beim Durchlaufen der Knoten nach den Prinzipien "Inorder (LWR)", "Praeorder WLR" und "Postorder (LRW)". 1. A B C D E F G H I J K L "Praeorder": A B C E I F J D G H K L "Inorder": E I C F J B G D K H L A "Postorder": I E J F C G K L H D B A 8 vgl. pr
32 2. + * + A B * E C D "Praeorder": + * A B + * C D E "Inorder": A * B + C * D + E "Postorder": A B * C D * E + + Diese Aufgabe zeigt einen Strukturbaum (Darstellung der hierarchischen Struktur eines arithmetischen Ausdrucks). Diese Baumdarstellung ist besonders günstig für die Übersetzung eines Ausdrucks in Maschinensprache. Aus der vorliegenden Struktur lassen sich leicht die unterschiedlichen Schreibweisen eines arithmetischen Ausdrucks herleiten. So liefert das Durchwandern des Baums in "Postorder" die Postfixnotation, in "Praeorder" die Praefixnotation" A * B C "Praeorder": + A * B C "Inorder": A + B * C "Postorder": A B C * + 4. * + C A B "Praeorder": * + A B C "Inorder": A + B * C "Postorder": A B + C * 32
33 Anwendungen der Durchlaufprinzipien Mit Hilfe der angegebenen Ordnungen bzw. Durchlaufprinzipien lassen sich weitere Operationen auf geordneten Wurzelbäumen bestimmen: a) C++ Anwendungen 1. Bestimmen der Anzahl Blätter im Baum // Anzahl Blätter template <class T> void anzblaetter(baumknoten<t>* b, int& zaehler) // benutze den Postorder Durchlauf if (b!= NULL) anzblaetter(b >holelinks(), zaehler); anzblaetter(b >holerechts(), zaehler); // Pruefe, ob der erreichte Knoten ein Blatt ist if (b >holelinks() == NULL && b >holerechts() == NULL) zaehler++; 2. Ermitteln der Höhe des Baums // Hoehe des Baums template <class T> int hoehe(baumknoten<t>* b) int hoehelinks, hoeherechts, hoehewert; if (b == NULL) hoehewert = 1; else hoehelinks = hoehe(b >holelinks()); hoeherechts = hoehe(b >holerechts()); hoehewert = 1 + (hoehelinks > hoeherechts? hoehelinks : hoeherechts); return hoehewert; 3. Kopieren des Baums // Kopieren eines Baums template <class T> baumknoten<t>* kopierebaum(baumknoten<t>* b) baumknoten<t> *neuerlzgr, *neuerrzgr, *neuerknoten; // Rekursionsendebedingung if (b == NULL) return NULL; if (b >holelinks()!= NULL) neuerlzgr = kopierebaum(b >holelinks()); else neuerlzgr = NULL; if (b >holerechts()!= NULL) neuerrzgr = kopierebaum(b >holerechts()); else neuerrzgr = NULL; // Der neue Baum wird von unten her aufgebaut, // zuerst werden die Nachfolger bearbeitet und // dann erst der Vaterknoten neuerknoten = erzeugebaumknoten(b >daten, neuerlzgr, neuerrzgr); // Rueckgabe des Zeigers auf den zuletzt erzeugten Baumknoten return neuerknoten; 4. Löschen des Baums 33
34 // Loeschen des Baums template <class T> void loeschebaum(baumknoten<t>* b) if (b!= NULL) loeschebaum(b >holelinks()); loeschebaum(b >holerechts()); gibknotenfrei(b); b) Java Anwendungen Grafische Darstellung eines binaeren Suchbaums 9 private void zeichnebaum(binaerbaumknoten b, int x, int y, int m, int s) Graphics g = meincanvas.getgraphics(); if (b!= null) if (b.links!= null) g.drawline(x,y,x m / 2,y + s); zeichnebaum(b.links,x m / 2,y + s,m / 2,s); if (b.rechts!= null) g.drawline(x,y,x + m / 2,y+s); zeichnebaum(b.rechts,x + m / 2,y + s,m / 2,s); 9 vgl. pr
35 4.3 Balancierte Bäume Hier geht es darum, entartete Bäume (schiefe Bäume, Äste werden zu linearen Listen, etc.) zu vermeiden. Statische Optimierung heißt: Der ganze Baum wird neu (bzw. wieder neu) aufgebaut. Bei der dynamischen Optimierung wird der Baum während des Betriebs (bei jedem Ein und Ausfügen) optimiert. Perfekt ausgeglichener, binärer Suchbaum Ein binärer Suchbaum sollte immer ausgeglichen sein. Der folgende Baum ist zu einer linearen Liste degeneriert und läßt sich daher auch nicht viel schneller als eine lineare Liste durchsuchen. Ein derartiger binärer Suchbaum entsteht zwangsläufig, wenn die bei der Eingabe angegebene Schlüsselfolge in aufsteigend sortierter Reihenfolge vorliegt. Der vorliegende binäre Suchbaum ist selbstverständlich nicht ausgeglichen. Es gibt allerdings auch Unterschiede bei der Beurteilung der Ausgeglichenheit, z.b.: Die vorliegenden Bäume sind beide ausgeglichen. Der linke Baum ist perfekt ausbalanciert. Jeder Binärbaum ist perfekt ausbalanciert, falls jeder Knoten über einen linken und rechten Teilbaum verfügt, dessen Knotenzahl sich höchstens um den Wert 1 unterscheidet. Der rechte Teilbaum ist ein in der Höhe ausgeglichener (AVL 10 )Baum. Die Höhe der Knoten zusammengehöriger linker und rechter Teilbäume unterscheiden sich höchstens um den Wert 1. Jeder perfekt ausgeglichene Baum ist gleichzeitig auch ein in der Höhe ausgeglichener Binärbaum. Der umgekehrte Fall trifft allerdings nicht zu. Es gibt einen einfachen Algorithmus zum Erstellen eines pefekt ausgeglichenen Binärbaums, falls 10 nach den Afangsbuchstaben der Namen seiner Entdecker: Adelson, Velskii u. Landes 35
36 (1) die einzulesenden Schlüsselwerte sortiert in aufsteigender Reihenfolge angegeben werden (2) bekannt ist, wieviel Objekte (Schlüssel) werden müssen. import java.io.*; class PBBknoten // Instanzvariable protected PBBknoten links; protected PBBknoten rechts; public int daten; // Konstruktoren public PBBknoten() this(0,null,null); public PBBknoten(int datenelement) this(datenelement, null, null ); public PBBknoten(int datenelement, PBBknoten l, PBBknoten r) daten = datenelement; links = l; rechts = r; public PBBknoten getlinks() return links; public PBBknoten getrechts() return rechts; // linker Teilbaum // rechter Teilbaum // Dateninhalt der Knoten public class PBB static BufferedReader ein = new BufferedReader(new InputStreamReader( System.in)); // Instanzvariable PBBknoten wurzel; // Konstruktor public PBB(int n) throws IOException if (n == 0) wurzel = null; else int nlinks = (n 1) / 2; int nrechts = n nlinks 1; wurzel = new PBBknoten(); wurzel.links = new PBB(nLinks).wurzel; wurzel.daten = Integer.parseInt(ein.readLine()); wurzel.rechts = new PBB(nRechts).wurzel; public void ausgpbb() ausg(wurzel,0); private void ausg(pbbknoten b, int nspace) if (b!= null) ausg(b.rechts,nspace += 6); for (int i = 0; i < nspace; i++) System.out.print(" "); System.out.println(b.daten); 36
37 ausg(b.links, nspace); // Test public static void main(string args[]) throws IOException int n; System.out.print("Gib eine ganze Zahl n an, "); System.out.print("gefolgt von n ganzen Zahlen in "); System.out.println("aufsteigender Folge"); n = Integer.parseInt(ein.readLine()); PBB b = new PBB(n); System.out.print( "Hier ist das Resultat: ein perfekt balancierter Baum, "); System.out.println("die Darstellung erfogt um 90 Grad versetzt"); b.ausgpbb(); Schreibtischtest: Wird mit n = 10 aufgerufen, dann wird anschließend die Anzahl der Knoten berechnet, die sowohl in den linken als auch in den rechten Teilbaum eingefügt werden. Da der Wurzelknoten keinem Teilbaum zugeordnet werden kann, ergeben sich für die beiden Teilbäume (10 1) Knoten. Das ergibt nlinks = 4, nrechts = 5. Anschließend wird der Wurzelknoten erzeugt. Es folgt der rekursive Aufruf wurzel.links = new PBB(nLinks).wurzel; mit nlinks = 4. Die Folge davon ist: Einlesen von 4 Zahlen und Ablage dieser Zahlen im linken Teilbaum. Die danach folgende Zahl wird im Wurzelknoten abgelegt. Der rekursive Aufruf wurzel.rechts = new PBB(nRechts).wurzel; mit nrechts = 5 verarbeitet die restlichen 5 Zahlen und erstellt damit den rechten Teilbaum. Durch jedem rekursiven Aufruf wird ein Baum mit zwei ungefähr gleich großen Teilbäumen erzeugt. Da die im Wurzelknoten enthaltene Zahl direkt nach dem erstellen des linken Teilbaum gelesen wird, ergibt sich bei aufsteigender Reihenfolge der Eingabedaten ein binärer Suchbaum, der außerdem noch perfekt balanciert ist. 37
38 4.3.1 Statisch optimierte Bäume Der Algorithmus zum Erstellen eines perfekt ausgeglichenen Baums kann zur statischen Optimierung binärer Suchbäume verwendet werden. Das Erstellen des binären Suchbaums erfolgt dabei nach der bekannten Verfahrensweise. Wird ein solcher Baum in Inorder Folge durchlaufen, so werden die Informationen in den Baumknoten aufsteigend sortiert. Diese sortierte Folge ist Eingangsgröße für die statische Optimierung. Es wird mit der sortiert vorliegende Folge der Schlüssel ein perfekt ausgeglichener Baum erstellt. Bsp.: Ein Java Applet zur Demonstration der statischen Optimierung. 11 Zufallszahlen werden generiert und in einen freien binären Intervallbaum aufgenommen, der im oberen Bereich des Fensters gezeigt werden. Über Sortieren erfolgt ein Inorder Durchlauf des binären Suchbaums, über "Perfekter BinaerBaum" Erzeugen und Darstellen des perfekt ausgeglichen binären Suchbaums. 11 vgl. pr43205, ZPBBApplet.java und ZPBBApplet.html 38
39 4.3.2 AVL Baum Der wohl bekannteste dynamisch ausgeglichene Binärbaum ist der AVL Baum, genannt nach dem Anfangsbuchstaben seiner Entdecker (Adelson, Velskii und Landis). Ein Baum hat die AVL Eigenschaft, wenn in jedem Knoten sich die Höhen der beiden Unterbäume höchstens um 1 ( HR HL <= 1) unterscheiden. Die Last ("Balance") muß in einem Knoten mitgespeichert sein. Es genügt aber als Maß für die Unsymmetrie die Höhendifferenz H festzuhalten, die nur die Werte 1 (linkslastig), 0 (gleichlastig) und +1 (rechtslastig) annehmen kann. 1. Einfügen Beim Einfügen eines Knoten können sich die Lastverhältnisse nur auf dem Wege, den der Suchvorgang in Anspruch nimmt, ändern. Der tatsächliche Ort der Änderung ist aber zunächst unbekannt. Der Knoten ist deshalb einzufügen und auf notwendige Berichtigungen zu überprüfen. Bsp.: Gegeben ist der folgende binäre Baum ) In diesen Baum sind die Knoten mit den Schlüsseln 9 und 11 einzufügen. Die Gestalt des Baums ist danach: Die Schlüsel 9 und 11 können ohne zusätzliches Ausgleichen eingefügt werden. 39
40 2) In den gegebenen Binärbaum sind die Knoten mit den Schlüsseln 1, 3, 5 und 7 einzufügen. Wie ist die daraus resultierende Gestalt des Baums beschaffen? Schon nach dem Einfügen des Schlüsselwerts "1" ist anschließendes Ausgleichen unbedingt erforderlich. 3) Wie könnte das Ausgleichen vollzogen werden? Eine Lösungsmöglichkeit ist hier bspw. eine einfache bzw. eine doppelte Rotation Gestalt des baums nach "Rotation" b) Beschreibe den Ausgleichsvorgang, nachdem die Schlüssel 3, 5 und 7 eingefügt wurden! Das Einfügen der Schlüssel mit den Werten "3", "5" und "7" verletzt die AVL Eigenschaft nicht Nachdem ein Knoten eingefügt ist, ist der Pfad, den der Suchvorgang für das Einfügen durchlaufen hat, aufwärts auf notwendige Berichtigungen zu überprüfen. Bei dieser Prüfung wird die Höhendifferenz des linken und rechten Teilbaums bestimmt. Es können generell folgende Fälle eintreten: 40
41 (1) H = +1 bzw. 1 Eine Verlängerung des Baums auf der Unterlastseite gleicht die Last aus, die Verlängerung wirkt sich nicht weiter nach oben aus. Die Prüfung kann abgebrochen werden. (2) H = 0 Das bedeutet: Verlängerung eines Teilbaums Hier ist der Knoten dann ungleichlastig ( H = +1 bzw. 1), die AVL Eigenschaft bleibt jedoch insgesamt erhalten. Der Baum wurde länger. (3) H = +1 bzw. 1 Das bedeutet: Verlängerung des Baums auf der Überlastseite. Die AVL Eigenschaft ist verletzt, wenn H = +2 bzw. 2. Sie wird durch Rotationen berichtigt. Die Information über die Ausgeglichenheit steht im AVL Baumknoten, z.b.: struct knoten int num, // Schluessel bal; // Ausgleichsfaktor struct knoten *zlinks, *zrechts; ; AVL Baumknoten mit Ausgleichfaktor in C++ In der Regel gibt es folgende Faktoren für die "Ausgeglichenheit" je Knoten im AVL Baum: " 1": Höhe des linken Teilbaums ist um eine Einheit (ein Knoten) größer als die Höhe im rechten Teilbaum. "0": Die Höhen des linken und rechten Teilbaums sind gleich. "1": Die Höhe des linken Teilbaums ist um eine Einheit (ein Knoten) kleiner als die Höhe des rechten Teilbaums. Bsp.: Die folgende Darstellung zeigt den Binärbaum unmittelbar nach dem Einfügen eines Baumknoten. Daher kann hier der Faktor für Ausgeglichenheit 2 bis 2 betragen
42 42
43 Nach dem Algorithmus für das Einfügen ergibt sich folgender AVL Baum: Es gibt 4 Möglichkeiten die Ausgeglichenheit, falls sie durch Einfügen eines Baumknoten gestört wurde, wieder herzustellen. A A A A B a a B B a a B b b c c b b c c 1a 1b 2a 2b Die vier Ausgangssituationen bei der Wiederherstellung der AVL Eigenschaft Von den 4 Fällen sind jeweils die Fälle 1a, 1b und die Fälle 2a, 2b zueinander symmetrisch. Für den Fall 1a kann durch einfache Rotation eine Ausgeglichenheit erreicht werden. B b 0 A c 0 a Im Fall 1b muß die Rotation nach links erfolgen. 43
44 Für die Behandlung von Fall 2a der Abb. 1 wird der Teilbaum c aufgeschlüsselt in dessen Teilbäume c1 und c2: A B 2 a b 2 C 1 c1 c2 Durch zwei einfache Rotationen kann der Baum ausgeglichen werden: 1. Rotation 2. Rotation A C 2 0 C a B A a B c2 b c1 c2 b +1 c1 a) Implementierung in C++ Mit der unter 1. festgestellten Verfahrensweise soll eine Klasse AVLBaum bestimmt werden, die Knoten der zuvor angegebenen Struktur so in einen Binärbaum einfügt, daß die AVL Eigenschaft gewährleistet bleibt. // avl: Demonstrationsprogramm fuer AVL Baeume // Einfuegen und Loeschen von Knoten #include <iostream.h> #include <iomanip.h> #include <ctype.h> struct knoten int num, bal; 44
45 struct knoten *zlinks, *zrechts; ; class AVLbaum private: knoten *wurzel; void LinksRotation(knoten* &z); void RechtsRotation(knoten* &z); int einf(knoten* &z, int x); void aus(const knoten *z, int nleerzeichen) const; public: AVLbaum():wurzel(NULL) void einfuegen(int x)einf(wurzel, x); void ausgabe()constaus(wurzel, 0); ; Methoden. void AVLbaum::LinksRotation(knoten* &z) knoten *hz = z; z = z >zrechts; hz >zrechts = z >zlinks; z >zlinks = hz; hz >bal ; if (z >bal > 0) hz >bal = z >bal; z >bal ; if (hz >bal < 0) z >bal += hz >bal; void AVLbaum::RechtsRotation(knoten* &z) knoten *hz = z; z = z >zlinks; hz >zlinks = z >zrechts; z >zrechts = hz; hz >bal++; if (z >bal < 0) hz >bal = z >bal; z >bal++; if (hz >bal > 0) z >bal += hz >bal; int AVLbaum::einf(knoten* &z, int x) // Rueckgabewert: Anstieg in der Hoehe // (0 or 1) nach Einfuegen von x in den // Teilbaum mit Wurzel z int deltah = 0; if (z == NULL) z = new knoten; z >num = x; z >bal = 0; z >zlinks = z >zrechts = NULL; deltah = 1; // Die Hoehe des Baums waechst um 1 else if (x > z >num) if (einf(z >zrechts, x)) z >bal++; // Die Hoehe des rechten Teilbaums waechst if (z >bal == 1) deltah = 1; else if (z >bal == 2) if (z >zrechts >bal == 1) RechtsRotation(z >zrechts); LinksRotation(z); else if (x < z >num) if (einf(z >zlinks, x)) z >bal ; // Hoehe vom linken Teilbaum waechst if (z >bal == 1) deltah = 1; else if (z >bal == 2) 45
46 if (z >zlinks >bal == 1) LinksRotation(z >zlinks); RechtsRotation(z); return deltah; b) Die generische Klasse "AvlBaum" in Java Grundlagen: Die AVL Eigenschaft ist verletzt, wenn diese Höhendifferenz +2 bzw. 2 ist. Der Knoten, der diesen Wert erhalten hat, ist der Knoten "alpha", dessen Unausgeglichenheit auf einen der folgenden 4 Fälle zurückzuführen ist: 1. Einfügen in den linken Teilbaum, der vom linken Nachkommen des Knoten "alpha" bestimmt ist. 2. Einfügen in den rechten Teilbaum, der vom linken Nachkommen des Knoten "alpha" bestimmt ist. 3. Einfügen in den linken Teilbaum, der vom rechten Nachkommen des Knoten "alpha" bestimmt ist. 4. Einfügen in den rechten Teilbaum, der vom rechten Nachkommen des Knoten "alpha" bestimmt ist Fall 1 und Fall 4 bzw. Fall 2 und Fall 3 sind Spiegelbilder, zeigen also das gleiche Verhalten. Fall 1 kann durch einfache Rotation behandelt werden und ist leicht zu bestimmen, daß das Einfügen "außerhalb" (links links bzw. rechts rechts im Fall 4 stattfindet. Fall 2 kann durch doppelte Rotation behandelt werden und ist ebenfalls leicht zu bestimmen, da das Einfügen "innerhalb" (links rechts bzw. rechts links) erfolgt. Die einfache Rotation: Die folgende Darstellung beschreibt den Fall 1 vor und nach der Rotation: 46
47 k2 k1 k1 Z k2 Y X Y Z X Die folgende Darstellung beschreibt Fall 4 vor und nach der Rotation: k1 k2 k2 k1 X Y X Y Z Z Doppelrotation: Die einfache Rotation führt in den Fällen 2 und 3 nicht zum Erfolg. Fall 2 muß durch eine Doppelrotation (links rechts) behandelt werden. k3 k2 k1 k1 k3 D A k2 D B C A B C 47
48 Auch Fall 3 muß durch Doppelrotation behandelt werden k1 k2 k2 k1 k3 A k3 D B C A D B C Implementierung: Zum Einfügen eines Knoten mit dem Datenwert "x" in einen AVL Baum, wird "x" rekursiv in den betoffenen Teilbaum eingesetzt. Falls die Höhe dieses Teilbaums sich nicht verändert, ist das Einfügen beendet. Liegt Unausgeglichenheit vor, dann ist einfache oder doppelte Rotation (abhängig von "x" und den Daten des betroffenen Teilbaums) nötig. Avl Baumknoten 12 Er enthält für jeden Knoten eine Angabe zur Höhe(ndifferenz) seiner Teilbäume. // Baumknoten fuer AVL Baeume class AvlKnoten // Instanzvariable protected AvlKnoten links; // Linkes Kind protected AvlKnoten rechts; // Rechtes Kind protected int hoehe; // Hoehe public Comparable daten; // Das Datenelement // Konstruktoren public AvlKnoten(Comparable datenelement) this(datenelement, null, null ); public AvlKnoten( Comparable datenelement, AvlKnoten lb, AvlKnoten rb ) daten = datenelement; links = lb; rechts = rb; hoehe = 0; 12 vgl. pr
49 Der Avl Baum 13 Bei jedem Schritt ist festzustellen, ob die Höhe des Teilbaums, in dem ein Element eingefügt wurde, zugenommen hat. * Rueckgabe: Hoehe des Knotens, oder 1, falls null. private static int hoehe(avlknoten b) return b == null? 1 : b.hoehe; Die Methode "insert" führt das Einfügen eines Baumknoten in den Avl Baum aus: * Interne Methode zum Einfuegen eines Baumknoten in einen Teilbaum. * x ist das einzufuegende Datenelement. * b ist der jeweilige Wurzelknoten. * Rueckgabe der neuen Wurzel des jeweiligen Teilbaums. private AvlKnoten insert(comparable x, AvlKnoten b) if( b == null ) b = new AvlKnoten(x, null, null); else if (x.compareto( b.daten) < 0 ) b.links = insert(x, b.links ); if (hoehe( b.links ) hoehe( b.rechts ) == 2 ) if (x.compareto( b.links.daten ) < 0 ) b = rotationmitlinksnachf(b); else b = doppelrotationmitlinksnachf(b); else if (x.compareto( b.daten ) > 0 ) b.rechts = insert(x, b.rechts); if( hoehe(b.rechts) hoehe(b.links) == 2) if( x.compareto(b.rechts.daten) > 0 ) b = rotationmitrechtsnachf(b); else b = doppelrotationmitrechtsnachf( b ); else ; // Duplikat; tue nichts b.hoehe = max( hoehe( b.links ), hoehe( b.rechts ) ) + 1; return b; Rotationen * Rotation Binaerbaumknoten mit linkem Nachfolger. * Fuer AVL Baeume ist dies eine einfache Rotation (Fall 1). * Aktualisiert Angaben zur Hoehe, dann Rueckgabe der neuen Wurzel. private static AvlKnoten rotationmitlinksnachf(avlknoten k2) AvlKnoten k1 = k2.links; k2.links = k1.rechts; k1.rechts = k2; 13 vgl. pr
50 k2.hoehe = max( hoehe( k2.links ), hoehe( k2.rechts ) ) + 1; k1.hoehe = max( hoehe( k1.links ), k2.hoehe ) + 1; return k1; * Rotation Binaerbaumknoten mit rechtem Nachfolger. * Fuer AVL Bäume ist dies eine einfache Rotation (Fall 4). * Aktualisiert Angaben zur Hoehe,, danach Rueckgabe der neuen Wurzel. private static AvlKnoten rotationmitrechtsnachf(avlknoten k1) AvlKnoten k2 = k1.rechts; k1.rechts = k2.links; k2.links = k1; k1.hoehe = max( hoehe( k1.links ), hoehe( k1.rechts ) ) + 1; k2.hoehe = max( hoehe( k2.rechts ), k1.hoehe ) + 1; return k2; * Doppelrotation der Binaerbaumknoten: : erster linker Nachfolgeknoten * mit seinem rechten Nachfolger; danach Knoten k3 mit neuem linken * Nachfolgerknoten. * Fuer AVL Baeume ist dies eine doppelte Rotation (Fall 2) * Aktualisiert Angaben zur Hoehe,, danach Rueckgabe der neuen Wurzel. private static AvlKnoten doppelrotationmitlinksnachf(avlknoten k3) k3.links = rotationmitrechtsnachf( k3.links ); return rotationmitlinksnachf( k3 ); * Doppelrotation der Binaerbaumknoten: erster rechter Nachfolgeknoten * mit seinem linken Nachfolger;danach Knoten k1 mit neuem rechten * Nachfolgerknoten * Fuer AVL Baeume ist dies eine doppelte Rotation (Fall 3) * Aktualisiert Angaben zur Hoehe,, danach Rueckgabe der neuen Wurzel. private static AvlKnoten doppelrotationmitrechtsnachf(avlknoten k1) k1.rechts = rotationmitlinksnachf(k1.rechts); return rotationmitrechtsnachf(k1); 50
51 2. Löschen Man kann folgende Fälle unterscheiden: (1) H = +1 bzw. 1 (Verkürzung des Teilbaums auf der Überlastseite) (2) H = 0 (Verkürzung eines Unterbaums) Der Knoten ist jetzt ungleichlastig ( H = +1 bzw. 1), bleibt jedoch im Rahmen der AVL Eigenschaft. Der Baum hat seine Höhe nicht verändert, die Berichtigung kann abgebrochen werden. (3) H = +1 bzw. 1 (Verkürzung eines Baums auf der Unterlastseite) Die AVL Eigenschaft ist verletzt, falls H = +2 bzw. 2. Sie wird durch eine Einfach bzw. Doppelrotation wieder hergestellt. Dadurch kann sich der Baum verkürzen, so daß Lastreduzierungen an den Vorgänger weiterzugeben sind. Es können aber auch Lastsituationen mit dem Lastfaktor 0 auftreten. Bsp.: Spezialfälle zum Lastausgleich in einem AVL Baum k k H+2 H+1 a k H+1 H+1 k H H+1 c b c a b k k H+2 H+1 a k k H H H H k d a b Löschen kann in der Regel nicht mit einer einzigen Rotation abgeschlossen werden. Im schlimmsten Fall erfordern alle Knoten im Pfad der Löschstelle eine Rekonfiguration. Experimente zeigen allerdings, daß beim Einfügen je Operation mehr Rotationen durchzuführen sind als beim Löschen. Offenbar existieren beim Löschen durch den inneren Bereich des Baums mehr Knoten, die ohne weiteres eliminiert werden können. 51
52 Aufgabe 1. Gegeben ist die Schlüsselfolge 7, 6, 8, 5, 9, 4. Ermittle, wie sich mit dieser Schlüsselfolge einen AVL Baum aufbaut. Schlüssel BALANCE LINKS, RECHTS Aus dem nun vorliegenden AVL Baum sind die Knoten mit den Schlüsselwerten 9 und 8 zu löschen. Gib an, welche Gestalt der AVL Baum jeweils annimmt. Schlüssel BALANCE LINKS, RECHTS
53 4.3.3 Splay Bäume Zugrundeliegende Idee Nachdem auf einen Baumknoten zugegriffen wurde, wird dieser Knoten über eine Reihe von AVL Rotationen zur Wurzel. Bis zu einem gewissen Grade führt das zur Ausbalancierung. Bsp.: 1. y x x C A y A B B C 2. e e e d F d F d F c E c E a E b a b A a D A b c C D B B C C D A B E a a F c e c d d A B F b b A B E E C D C D 53
54 Splaying Operationen Der Knoten "x" im Splay Baum bewegt sich über einfache und doppelte Rotationen zur Wurzel. Man unerscheidet folgende Fälle: 1. (zig): x ist ein Kind der Wurzel von einem Splay Baum, einfache Rotation 2. (zig zig): x hat den Großvater g(x) und den Vater p(x), x und p(x) sind jeweils linke (bzw. rechte) Kinder ihres Vaters. g(x)=p(y) bzw. g(x) y = p(x) p(x) x C D A B x A B C D x A y B z C D 3. (zig zag): x hat Großvater g(x) und Vater p(x), x ist linkes (rechtes) Kind von p(x), p(x) ist rechtes (linkes) Kind von g(x) z = g(x) x y=p(x) y z D A x A B C D B C 54
55 Implementierung 14 BinaerBaumKnoten // Elementarer Knoten eines binaeren Baums, der nicht ausgeglichen ist // Der Zugriff auf diese Klasse ist nur innerhalb eines Verzeichnisses // bzw. Pakets moeglich class BinaerBaumknoten // Instanzvariable protected BinaerBaumknoten links; protected BinaerBaumknoten rechts; // linker Teilbaum // rechter Teilbaum // Dateninhalt der Knoten public Comparable daten; // Konstruktor public BinaerBaumknoten(Comparable datenelement) this(datenelement, null, null ); public BinaerBaumknoten(Comparable datenelement, BinaerBaumknoten l, BinaerBaumknoten r) daten = datenelement; links = l; rechts = r; public void insert (Comparable x) if (x.compareto(daten) > 0) // dann rechts if (rechts == null) rechts = new BinaerBaumknoten(x); else rechts.insert(x); else // sonst links if (links == null) links = new BinaerBaumknoten(x); else links.insert(x); public BinaerBaumknoten getlinks() return links; public BinaerBaumknoten getrechts() return rechts; SplayBaum // SplayBaum class // // ***************** PUBLIC OPERATIONen ******************** // void insert( x ) > Insert x // void remove( x ) > Remove x // Comparable find( x ) > Gib das Merkmal zurück, das x zugeordnet ist // Comparable findmin( ) > Rueckgabe des kleinsten elements // Comparable findmax( ) > Rueckgabe des groessten Elements 14 pr
56 // boolean isempty( ) > Rueckgabe true, falls leer; sonst false // void makeempty( ) > Entferne alle Elemente // void printtree( ) > Gib den Baum sortiert aus * Implementiere einen top down Splay Baum. * Vergleiche beziehen sich auf die Methode compareto. public class SplayBaum private BinaerBaumknoten root; private static BinaerBaumknoten nullnode; static // Static initializer for nullnode nullnode = new BinaerBaumknoten( null ); nullnode.links = nullnode.rechts = nullnode; private static BinaerBaumknoten newnode = null; // wird in diversen Einfuegevorgaengen benutzt private static BinaerBaumknoten header = new BinaerBaumknoten(null); * Konstruktor. public SplayBaum( ) root = nullnode; * Zugriff auf die Wurzel public BinaerBaumknoten holewurzel() return root; * Insert. * Parameter x ist das einzufuegende Element. public void insert( Comparable x ) if( newnode == null ) newnode = new BinaerBaumknoten( null ); newnode.daten = x; if( root == nullnode ) newnode.links = newnode.rechts = nullnode; root = newnode; else root = splay( x, root ); if( x.compareto( root.daten ) < 0 ) newnode.links = root.links; newnode.rechts = root; root.links = nullnode; root = newnode; else if( x.compareto( root.daten ) > 0 ) newnode.rechts = root.rechts; newnode.links = root; root.rechts = nullnode; 56
57 root = newnode; else return; newnode = null; * Remove. * Parameter x ist das zu entfernende Element. public void remove( Comparable x ) BinaerBaumknoten neuerbaum; // Falls x gefunden wird, liegt x in der Wurzel root = splay( x, root ); if( root.daten.compareto( x )!= 0 ) return; // Element nicht gefunden; tue nichts if( root.links == nullnode ) neuerbaum = root.rechts; else // Finde das Maximum im linken Teilbaum // Splay es zur Wurzel; dann haenge das rechte Kind dran neuerbaum = root.links; neuerbaum = splay( x, neuerbaum ); neuerbaum.rechts = root.rechts; root = neuerbaum; * Bestimme das kleinste Daten Element im Baum. * Rueckgabe: kleinstes Datenelement bzw. null, falls leer. public Comparable findmin( ) if( isempty( ) ) return null; BinaerBaumknoten ptr = root; while( ptr.links!= nullnode ) ptr = ptr.links; root = splay( ptr.daten, root ); return ptr.daten; * Bestimme das groesste Datenelement im Baum. * Rueckgabe: das groesste Datenelement bzw. null, falls leer public Comparable findmax( ) if (isempty( )) return null; BinaerBaumknoten ptr = root; while( ptr.rechts!= nullnode ) ptr = ptr.rechts; root = splay( ptr.daten, root ); return ptr.daten; * Bestimme ein Datenelement im Baum. * Parameter x entfält das zu suchende Element. * Rueckgabe: Das passende Datenelement oder null, falls leer public Comparable find( Comparable x ) root = splay( x, root ); if (root.daten.compareto( x )!= 0) return null; return root.daten; 57
58 * Mache den Baum logisch leer. public void makeempty( ) root = nullnode; * Ueberpruefe, ob der Baum logisch leer ist * Rueckgabe true, falls leer, anderenfalls false. public boolean isempty( ) return root == nullnode; * Gib den Inhalt des baums in sortierter Folge aus. public void printtree( ) if (isempty( )) System.out.println( "Empty tree" ); else printtree( root ); * Ausgabe des Binaerbaums um 90 Grad versetzt public void ausgbinaerbaum(binaerbaumknoten b, int stufe) if (b!= b.links) ausgbinaerbaum(b.links,stufe + 3); for (int i = 0; i < stufe; i++) System.out.print( ); System.out.println(b.daten.toString()); ausgbinaerbaum(b.rechts,stufe + 3); * Interne Methode zur Ausfuehrung eines "top down" splay. * Der zuletzt im Zugriff befindliche Knoten * wird die neue Wurzel. * Parameter x Ist das Zielelement, die Umgebung fuer das Splaying. * Parameter b ist die Wurzel des Teilbaums, * um den das Splaying stattfindet. * Rueckgabe des Teilbaums. private BinaerBaumknoten splay( Comparable x, BinaerBaumknoten t ) BinaerBaumknoten lefttreemax, righttreemin; header.links = header.rechts = nullnode; lefttreemax = righttreemin = header; nullnode.daten = x; // Guarantee a match for( ; ; ) if( x.compareto( t.daten ) < 0 ) if( x.compareto( t.links.daten ) < 0 ) t = rotatewithleftchild( t ); if( t.links == nullnode ) break; 58
59 // Kette Rechts righttreemin.links = t; righttreemin = t; t = t.links; else if( x.compareto( t.daten ) > 0 ) if( x.compareto( t.rechts.daten ) > 0 ) t = rotatewithrightchild( t ); if( t.rechts == nullnode ) break; // Kette Links lefttreemax.rechts = t; lefttreemax = t; t = t.rechts; else break; lefttreemax.rechts = t.links; righttreemin.links = t.rechts; t.links = header.rechts; t.rechts = header.links; return t; * Rotation BinaerBaumknoten mit linkem Nachfolger. static BinaerBaumknoten rotatewithleftchild(binaerbaumknoten k2) BinaerBaumknoten k1 = k2.links; k2.links = k1.rechts; k1.rechts = k2; return k1; * Rotation BinaerBaumknoten mit rechtem Nachfolger. static BinaerBaumknoten rotatewithrightchild(binaerbaumknoten k1) BinaerBaumknoten k2 = k1.rechts; k1.rechts = k2.links; k2.links = k1; return k2; * Interne Methode zur Ausgabe eines Teilbaums in sortierter Folge. * Parameter b ist der jweilige Wurzelknoten. private void printtree( BinaerBaumknoten b ) if( b!= b.links ) printtree(b.links); System.out.println(b.daten.toString( )); printtree(b.rechts); SplaybaumTest import java.io.*; public class SplayBaumTest 59
60 public static void main( String [ ] args ) SplayBaum b = new SplayBaum(); String eingabezeile = null; System.out.println("Einfuegen"); BufferedReader eingabe = null; eingabe = new BufferedReader( new InputStreamReader(System.in)); try int zahl; do System.out.println("Zahl? "); eingabezeile = eingabe.readline(); try zahl = Integer.parseInt(eingabeZeile); b.insert(new Integer(zahl)); b.ausgbinaerbaum(b.holewurzel(),2); catch (NumberFormatException ne) break; while (eingabezeile!= ""); catch (IOException ioe) System.out.println("Eingefangen in main()"); System.out.println("Loeschen"); try int zahl; do System.out.println("Zahl? "); eingabezeile = eingabe.readline(); try zahl = Integer.parseInt(eingabeZeile); b.remove(new Integer(zahl)); b.ausgbinaerbaum(b.holewurzel(),2); catch (NumberFormatException ne) break; while (eingabezeile!= ""); catch (IOException ioe) System.out.println("Eingefangen in main()"); System.out.println("Zugriff auf das kleinste Element"); b.findmin(); b.ausgbinaerbaum(b.holewurzel(),2); System.out.println("Zugriff auf das groesste Element"); b.findmax(); b.ausgbinaerbaum(b.holewurzel(),2); 60
61 4.3.4 Rot Schwarz Bäume Zum Ausschluß des ungünstigsten Falls bei binären Suchbäumen ist eine gewisse Flexibilität in den verwendeten Datenstrukturen nötig. Das kann bspw. durch Aufnahme von mehr als einem Schlüssel in Baumknoten erreicht werden. So soll es 3 Knoten bzw. 4 Knoten geben, die 2 bzw. 3 Schlüssel enthalten können: Ein 3 Knoten besitzt 3 von ihm ausgehende Verkettungen eine für alle Datensätze mit Schlüsseln, die kleiner sind als seine beiden Schlüssel eine für alle Datensätze, die zwischen den beiden Schlüsseln liegen eine für alle Datensätze mit Schlüsseln, die größer sind als seine beiden Schlüssel. Ein 4 Knoten besitzt vier von ihm ausgehende Verkettungen, nämlich eine Verkettung für jedes der Intervalle, die durch seine drei Schlüssel definiert werden. Es ist möglich Bäume als gewöhnliche binäre Bäume (mit nur zwei Knoten) darzustellen, wobei nur ein zusätzliches Bit je Knoten verwendet wird. Die Idee besteht darin, 3 Knoten und 4 Knoten als kleine binäre Bäume darzustellen, die durch "rote" Verkettungen miteinander verbunden sind, im Gegensatz zu den schwarzen Verkettungen, die den Baum zusammenhalten: oder 4 Knoten werden als 2 Knoten dargestellt, die mittels einer roten Verkettung verbunden sind. 3 Knoten werden als 2 Knoten dargestellt, die mit einer roten Markierung verbunden sind. Rot schwarze Darstellung von Bäumen Zu jedem Baum gibt es viele ihm entsprechende Rot Schwarz Bäume. Diese Bäume haben eine Reihe von Eigenschaften, die sich unmittelbar aus ihrer Definition ergeben, z.b.: Alle Pfade von der Wurzel zu einem Blatt haben dieselbe Anzahl von schwarzen Kanten. Dabei werden nur die Kanten zwischen inneren Knoten gezählt. Längs eines beliebigen Pfads treten niemals zwei rote Verkettungen nacheinander auf. Rot Schwarz Bäume erlauben es, AVL Bäume, perfekt ausgeglichene Bäume und viele andere Klassen binärer Bäume einheitlich zu repräsentieren und zu implementieren. 61
62 Eine Variante zu Rot Schwarz Bäumen Definition. Ein Rot Schwarz Baum ist ein Binärbaum mit folgenden Farbeigenschaften: 1. Jeder Knoten ist entweder rot oder schwarz gefärbt. 2. der Wurzelknoten ist schwarz gefärbt. 3. Falls ein Knoten rot gefärbt ist, müssen seine Nachfolger schwarz gefärbt sein. 4. Jeder Pfad von einem Knoten zu einer "Null Referenz" muß die gleiche Anzahl von schwarzen Knoten enthalten. Höhe. Eine Folgerung dieser Farbregeln ist: Die Höhe eines Rot Schwarz Baums ist etwa 2 log( N + 1). Suchen ist garantiert unter logn erfolgreich. Aufgabe: Ermittle, welche Gestalt jeweils ein nach den vorliegenden Farbregeln erstellte Rot Schwarz Baum beim einfügen folgenden Schlüssel " " annimmt
63
64 Die Abbildungen zeigen, daß im durchschnitt der Rot Schwarz Baum ungefähr die Tiefe eines AVL Baums besitzt. Der Vorteil von Rot Schwarz Bäumen ist der geringere Overhead zur Ausführung von Einfügevorgängen und die geringere Anzahl von Rotationen. 64
65 "Top Down" Rot Schwarz Bäume. Kann auf dem Weg nach unten festgestellt werden, daß ein Knoten X zwei rote Nachfolgeknoten hat, dann wird X rot und die beiden "Kinder" schwarz: X X c1 c2 c1 c2 Das führt zu einem Verstoß gegen Bedingung 3, falls der Vorgänger von X auch rot ist. In diesem Fall können aber geeignete Rotationen herangezogen werden: G P P S X G C A X B B S A C G X P S P G X C A A B1 B2 S B1 B2 C Der folgende Fall kann nicht eintreten: Der Nachbar vom Elternknoten ist rot gefärbt. Auf dem Weg nach unten muß der Knoten mit zwei roten Nachfolgern einen schwarzen Großvaterknoten haben. Methoden zur Ausführung der Rotation. * Interne Routine, die eine einfache oder doppelte Rotation veranlasst. * Da das Ergebnis an "parent" geheftet wird, gibt es vier Faelle. * Aufruf durch reorientierung. * "item" ist das Datenelement reorientierung. * "parent" ist "parent" von der wurzel des rotierenden Teilbaums. * Rueckgabe: Wurzel des rotierenden Teilbaums. private RotSchwarzKnoten rotation(comparable item, RotSchwarzKnoten parent) if (item.compareto(parent.daten) < 0) return parent.links = item.compareto( parent.links.daten) < 0? rotationmitlinksnachf(parent.links) : // LL rotationmitrechtsnachf(parent.links) ; // LR else return parent.rechts = item.compareto(parent.rechts.daten) < 0? rotationmitlinksnachf(parent.rechts) : // RL rotationmitrechtsnachf(parent.rechts); // RR * Rotation Binaerbaumknoten mit linkem Nachfolger. static RotSchwarzKnoten rotationmitlinksnachf( RotSchwarzKnoten k2 ) 65
66 RotSchwarzKnoten k1 = k2.links; k2.links = k1.rechts; k1.rechts = k2; return k1; * Rotate Binaerbaumknoten mit rechtem Nachfolger. static RotSchwarzKnoten rotationmitrechtsnachf(rotschwarzknoten k1) RotSchwarzKnoten k2 = k1.rechts; k1.rechts = k2.links; k2.links = k1; return k2; Implementierung in Java 15 Sie wird dadurch erschwert, daß einige Teilbäume (z.b. der rechte Teilbaum des Knoten 10 im vorliegenden Bsp.) leer sein können, und die Wurzel des Baums (, da ohne Vorgänger, ) einer speziellen Behandlung bedarf. Aus diesem Grund werden hier "Sentinel" Knoten verwendet: eine für die Wurzel. Dieser Knoten speichert den Schlüssel realen Knoten einen Nullknoten (nullnode), der eine Null Referenz anzeigt. und einen rechten Link zu dem Der Inorder Durchlauf nimmt aus diesem Grund folgende Gestalt an: Ausgabe der im Baum gespeicherten Datenelemente in sortierter Reihenfolge. public void printtree( ) if( isempty() ) System.out.println("Leerer Baum"); else printtree( header.rechts ); * Interne Methode fuer die Ausgabe des Baum in sortierter Reihenfolge. * b ist der Wurzelknoten. private void printtree(rotschwarzknoten b) if (b!= nullnode ) printtree(b.links); System.out.println(b.daten ); printtree(b.rechts ); Die Klasse RotSchwarzknoten // BaumKnoten fuer RotSchwarzBaeume class RotSchwarzKnoten // Instanzvariable public Comparable daten; // Dateninformation der Knoten protected RotSchwarzKnoten links; // linkes Kind 15 vgl. pr
67 protected RotSchwarzKnoten rechts; // rechtes Kind protected int farbe; // Farbe // Konstruktoren RotSchwarzKnoten(Comparable datenelement) this(datenelement, null, null ); RotSchwarzKnoten(Comparable datenelement, RotSchwarzKnoten l, RotSchwarzKnoten r) daten = datenelement; links = l; rechts = r; farbe = RotSchwarzBaum.BLACK; Das Gerüst der Klasse RotSchwarzBaum und Initialisierungsroutinen // Die Klasse RotSchwarzBaum // // Konstruktion: mit einem "negative infinity sentinel" // // ******************PUBLIC OPERATIONEN********************* // void insert(x) > Insert x // void remove(x) > Entferne x (nicht implementiert) // Comparable find(x) > Ruecggabe des Datenelements, das x enthaelt // Comparable findmin() > Rueckgabe des kleinsten Datenelements // Comparable findmax() > Rueckgabe des groessten Datenelements // boolean isempty() > Rueckgabe true, falls leer; anderenfalls false // void makeempty() > Entferne alles // void printtree() > Ausgabe in aufsteigend sortierter Folge // void ausgrotschwarzbaum() > Ausgabe des Baums um 90 Grad versetzt * Implementierung eines RotSchwarzBaum. * Vergleiche basieren auf der Methode compareto. public class RotSchwarzBaum private RotSchwarzKnoten header; private static RotSchwarzKnoten nullnode; static // Static Initialisierer for nullnode nullnode = new RotSchwarzKnoten(null); nullnode.links = nullnode.rechts = nullnode; static final int BLACK = 1; // Black must be 1 static final int RED = 0;?.. * Baumkonstruktion. * neginf ist ein Wert, der kleiner oder gleich zu allen anderen Werten ist. public RotSchwarzBaum(Comparable neginf) header = new RotSchwarzKnoten(negInf); header.links = header.rechts = nullnode;?.. Die Methode "insert" // Fuer "insert routine" und zugehoerige unterstuetzende Routinen private static RotSchwarzKnoten current; private static RotSchwarzKnoten parent; private static RotSchwarzKnoten grand; private static RotSchwarzKnoten great; 67
68 * Einfügen in den Baum. Duplikate werden ueberlesen. * "item" ist das einzufuegende Datenelement. public void insert(comparable item) current = parent = grand = header; nullnode.daten = item; while( current.daten.compareto( item )!= 0 ) great = grand; grand = parent; parent = current; current = item.compareto(current.daten ) < 0? current.links : current.rechts; // Pruefe, ob zwei rote Kinder; falls es so ist, fixiere es if( current.links.farbe == RED && current.rechts.farbe == RED ) reorientierung( item ); // Fehlanzeige fuer Einfuegen, falls schon da if( current!= nullnode ) return; current = new RotSchwarzKnoten( item, nullnode, nullnode ); // Anhaengen an die Eltern if( item.compareto( parent.daten ) < 0 ) parent.links = current; else parent.rechts = current; reorientierung( item ); * Interne Routine, die waehrend eines Einfuegevorgangs aufgerufen wird * Falls ein Knoten zwei rote Kinder hat, fuehre Tausch der Farben aus * und rotiere. * item enthaelt das einzufuegende Datenelement. private void reorientierung(comparable item) // Tausch der Farben current.farbe = RED; current.links.farbe = BLACK; current.rechts.farbe = BLACK; if (parent.farbe == RED) // Rotation ist noetig grand.farbe = RED; if ( (item.compareto( grand.daten) < 0 )!= (item.compareto( parent.daten) < 0 ) ) parent = rotation(item, grand); // Start Doppelrotation current = rotation(item, great); current.farbe = BLACK; header.rechts.farbe = BLACK; // Mache die Wurzel schwarz Bsp.: Java Applet 16 zur Darstellung eines Rot Schwarz Baums 16 vgl. pr
69 69
Algorithmen und Datenstrukturen
Übung 3: Die generische Klasse BinärerSuchbaum in Java 1 Datenelemente der Klasse BinaererSuchbaum Das einzige Datenelelement in dieser Klasse ist die Wurzel vom Typ BinaerBaumknoten. Die Klasse BinaerBaumknoten
MehrÜbung 4: Die generische Klasse AvlBaum in Java 1
Übung 4: Die generische Klasse AvlBaum in Java 1 Ein binärer Suchbaum hat die AVL -Eigenschaft, wenn sich in jedem Knoten sich die Höhen der beiden Teilbäume höchstens um 1 unterscheiden. Diese Last (
MehrAlgorithmen und Datenstrukturen 1
Algorithmen und Datenstrukturen 1 8. Vorlesung Martin Middendorf und Peter F. Stadler Universität Leipzig Institut für Informatik middendorf@informatik.uni-leipzig.de studla@bioinf.uni-leipzig.de Gefädelte
MehrAlgorithmen und Datenstrukturen 2. Dynamische Datenstrukturen
Algorithmen und Datenstrukturen 2 Dynamische Datenstrukturen Algorithmen für dynamische Datenstrukturen Zugriff auf Variable und Felder durch einen Ausdruck: Namen durch feste Adressen referenziert Anzahl
Mehr13. Bäume: effektives Suchen und Sortieren
Schwerpunkte Aufgabe und Vorteile von Bäumen 13. Bäume: effektives Suchen und Sortieren Java-Beispiele: Baum.java Traverse.java TraverseTest.java Sortieren mit Bäumen Ausgabealgorithmen: - Preorder - Postorder
MehrWiederholung. Bäume sind zyklenfrei. Rekursive Definition: Baum = Wurzelknoten + disjunkte Menge von Kindbäumen.
Wiederholung Baum: Gerichteter Graph, der die folgenden drei Bedingungen erfüllt: Es gibt einen Knoten, der nicht Endknoten einer Kante ist. (Dieser Knoten heißt Wurzel des Baums.) Jeder andere Knoten
MehrVorlesung Informatik 2 Algorithmen und Datenstrukturen
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (18 Bäume: Grundlagen und natürliche Suchbäume) Prof. Dr. Susanne Albers Bäume (1) Bäume sind verallgemeinerte Listen (jedes Knoten-Element kann mehr
MehrDatenstrukturen Teil 2. Bäume. Definition. Definition. Definition. Bäume sind verallgemeinerte Listen. Sie sind weiter spezielle Graphen
Bäume sind verallgemeinerte Listen Datenstrukturen Teil 2 Bäume Jeder Knoten kann mehrere Nachfolger haben Sie sind weiter spezielle Graphen Graphen bestehen aus Knoten und Kanten Kanten können gerichtet
MehrTeil 1: Suchen. Ausgeglichene Bäume B-Bäume Digitale Suchbäume. M.O.Franz, Oktober 2007 Algorithmen und Datenstrukturen - Binärbäume 1-1
Teil : Suchen Problemstellung Elementare Suchverfahren Hashverfahren Binäre Suchbäume (Wiederholung aus Prog 2) Bäume: Begriffe, Eigenschaften und Traversierung Binäre Suchbäume Gefädelte Suchbäume Ausgeglichene
Mehr(a, b)-bäume / 1. Datenmenge ist so groß, dass sie auf der Festplatte abgespeichert werden muss.
(a, b)-bäume / 1. Szenario: Datenmenge ist so groß, dass sie auf der Festplatte abgespeichert werden muss. Konsequenz: Kommunikation zwischen Hauptspeicher und Festplatte - geschieht nicht Byte für Byte,
MehrVorlesung Datenstrukturen
Vorlesung Datenstrukturen Binärbaum Suchbaum Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 356 Datenstruktur Binärbaum Strukturrepräsentation des mathematischen Konzepts Binärbaum
MehrDer linke Teilbaum von v enthält nur Schlüssel < key(v) und der rechte Teilbaum enthält nur Schlüssel > key(v)
Ein Baum T mit Knotengraden 2, dessen Knoten Schlüssel aus einer total geordneten Menge speichern, ist ein binärer Suchbaum (BST), wenn für jeden inneren Knoten v von T die Suchbaumeigenschaft gilt: Der
MehrIdee: Wenn wir beim Kopfknoten zwei Referenzen verfolgen können, sind die Teillisten kürzer. kopf Eine Datenstruktur mit Schlüsselwerten 1 bis 10
Binäre Bäume Bäume gehören zu den wichtigsten Datenstrukturen in der Informatik. Sie repräsentieren z.b. die Struktur eines arithmetischen Terms oder die Struktur eines Buchs. Bäume beschreiben Organisationshierarchien
MehrLogische Datenstrukturen
Lineare Listen Stapel, Warteschlangen Binärbäume Seite 1 Lineare Liste Begriffe first Funktion: sequentielle Verkettung von Datensätzen Ordnungsprinzip: Schlüssel Begriffe: first - Anker, Wurzel; Adresse
MehrÜbung 6. Rot-Schwarz-Bäume
Übung 6. Rot-Schwarz-Bäume Top-Down 2.-3-4-Bäume Zum Ausschluß des ungünstigsten Falls bei binären Suchbäumen ist eine gewisse Flexibilität in den verwendeten Datenstrukturen nötig. Das kann bspw. durch
Mehr3 Dynamische Datenstrukturen
3 Dynamische Datenstrukturen Beispiele für dynamische Datenstrukturen sind Lineare Listen Schlangen Stapel Bäume Prof. Dr. Dietmar Seipel 128 Praktische Informatik I - Algorithmen und Datenstrukturen Wintersemester
MehrEINI LogWing/WiMa. Einführung in die Informatik für Naturwissenschaftler und Ingenieure. Vorlesung 2 SWS WS 17/18
EINI LogWing/ Einführung in die Informatik für Naturwissenschaftler und Ingenieure Vorlesung 2 SWS WS 17/18 Dr. Lars Hildebrand Fakultät für Informatik Technische Universität Dortmund lars.hildebrand@tu-dortmund.de
MehrAlgorithmen und Datenstrukturen
Algorithmen und Datenstrukturen Dipl. Inform. Andreas Wilkens aw@awilkens.com Überblick Grundlagen Definitionen Elementare Datenstrukturen Rekursionen Bäume 2 1 Datenstruktur Baum Definition eines Baumes
Mehr1 AVL-Bäume. 1.1 Aufgabentyp. 1.2 Überblick. 1.3 Grundidee
AVL-Bäume. Aufgabentyp Fügen Sie in einen anfangs leeren AVL Baum die folgenden Schlüssel ein:... Wenden Sie hierbei konsequent den Einfüge /Balancierungsalgorithmus an und dokumentieren Sie die ausgeführten
MehrBäume. 2006 Jiri Spale, Algorithmen und Datenstrukturen - Bäume 1
Bäume 2006 Jiri Spale, Algorithmen und Datenstrukturen - Bäume 1 Inhalt Grundbegriffe: Baum, Binärbaum Binäre Suchbäume (Definition) Typische Aufgaben Suchaufwand Löschen allgemein, Methode Schlüsseltransfer
MehrEine Baumstruktur sei folgendermaßen definiert. Eine Baumstruktur mit Grundtyp Element ist entweder
Programmieren in PASCAL Bäume 1 1. Baumstrukturen Eine Baumstruktur sei folgendermaßen definiert. Eine Baumstruktur mit Grundtyp Element ist entweder 1. die leere Struktur oder 2. ein Knoten vom Typ Element
MehrKapitel 12: Induktive
Kapitel 12: Induktive Datenstrukturen Felix Freiling Lehrstuhl für Praktische Informatik 1 Universität Mannheim Vorlesung Praktische Informatik I im Herbstsemester 2009 Folien nach einer Vorlage von H.-Peter
MehrKapiteltests zum Leitprogramm Binäre Suchbäume
Kapiteltests zum Leitprogramm Binäre Suchbäume Björn Steffen Timur Erdag überarbeitet von Christina Class Binäre Suchbäume Kapiteltests für das ETH-Leitprogramm Adressaten und Institutionen Das Leitprogramm
MehrBinäre Bäume Darstellung und Traversierung
Binäre Bäume Darstellung und Traversierung Name Frank Bollwig Matrikel-Nr. 2770085 E-Mail fb641378@inf.tu-dresden.de Datum 15. November 2001 0. Vorbemerkungen... 3 1. Terminologie binärer Bäume... 4 2.
MehrAlgorithmen und Datenstrukturen 1-5. Seminar -
Algorithmen und Datenstrukturen 1-5. Seminar - Dominic Rose Bioinformatics Group, University of Leipzig Wintersemester 2009/10 Outline 5.+6. Übungsserie: 5 Aufgaben, insgesamt 40 Punkte A17 Baum-Traversierung
MehrAlgorithmen und Datenstrukturen 1
Algorithmen und Datenstrukturen 1 7. Vorlesung Peter F. Stadler Universität Leipzig Institut für Informatik studla@informatik.uni-leipzig.de aufbauend auf den Kursen der letzten Jahre von E. Rahm, G. Heyer,
Mehr9.4 Binäre Suchbäume. Xiaoyi Jiang Informatik II Datenstrukturen und Algorithmen
9.4 Binäre Suchbäume Erweiterung: Einfügen an der Wurzel Standardimplementierung: Der neue Schlüssel wird am Ende des Suchpfades angefügt (natürlich, weil zuerst festgestellt werden muss, ob der Schlüssel
MehrBäume. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 10: Collections 4. Inhalt. Bäume. Einführung. Bäume.
Universität Osnabrück 1 Bäume 3 - Objektorientierte Programmierung in Java Vorlesung 10: Collections 4 Einführung Bäume sind verallgemeinerte Listenstrukturen Lineare Liste Jedes Element hat höchstens
MehrADS: Algorithmen und Datenstrukturen
ADS: Algorithmen und Datenstrukturen Teil VII Peter F. Stadler & Konstantin Klemm Bioinformatics Group, Dept. of Computer Science & Interdisciplinary Center for Bioinformatics, University of Leipzig 08.
Mehr368 4 Algorithmen und Datenstrukturen
Kap04.fm Seite 368 Dienstag, 7. September 2010 1:51 13 368 4 Algorithmen und Datenstrukturen Java-Klassen Die ist die Klasse Object, ein Pfeil von Klasse A nach Klasse B bedeutet Bextends A, d.h. B ist
Mehr4.3 Bäume. Definition des Baumes. Bäume sind eine sehr wichtige Datenstruktur der Informatik.
4.3 Bäume Bäume sind eine sehr wichtige Datenstruktur der Informatik. Definition des Baumes Ein Baum besteht aus einer nichtleeren Menge von Knoten und einer Menge von Kanten. Jede Kante verbindet genau
MehrWiederholung. Datenstrukturen und. Bäume. Wiederholung. Suchen in linearen Feldern VO
Wiederholung Datenstrukturen und Algorithmen VO 708.031 Suchen in linearen Feldern Ohne Vorsortierung: Sequentielle Suche Speicherung nach Zugriffswahrscheinlichkeit Selbstanordnende Felder Mit Vorsortierung:
MehrTechnische Universität München. Vorlesungsgrobstruktur: wo stehen wir, wie geht s weiter
Vorlesungsgrobstruktur: wo stehen wir, wie geht s weiter Kapitel 7 Fortgeschrittene Datenstrukturen Motivation: Lineare Liste: Suchen eines Elements ist schnell O(log n) Einfügen eines Elements ist langsam
MehrCopyright, Page 1 of 8 AVL-Baum
www.mathematik-netz.de Copyright, Page 1 of 8 AVL-Baum 1. Motivation und Einleitung Das Suchen, Einfügen und entfernen eines Schlüssels in einem zufällige erzeugten binären Suchbaum mit N Schlüsseln ist
MehrProseminar Kodierverfahren bei Dr. Ulrich Tamm Sommersemester 2003 Thema: Codierung von Bäumen (Prüfer Codes...)
Proseminar Kodierverfahren bei Dr. Ulrich Tamm Sommersemester 2003 Thema: Codierung von Bäumen (Prüfer Codes...) Inhalt: Einleitung, Begriffe Baumtypen und deren Kodierung Binäre Bäume Mehrwegbäume Prüfer
MehrEinführung in die Informatik: Programmierung und Software-Entwicklung, WS 16/17. Kapitel 14. Bäume. Bäume 1
Kapitel 14 Bäume Bäume 1 Ziele Den Begriff des Baums in der Informatik kennenlernen Bäume als verkettete Datenstruktur repräsentieren können Rekursive Funktionen auf Bäumen verstehen und schreiben können
MehrBäume. Text. Prof. Dr. Margarita Esponda SS 2012 O4 O5 O6 O ALP2-Vorlesung, M. Esponda
Bäume O1 O2 Text O3 O4 O5 O6 O7 Prof. Dr. Margarita Esponda SS 2012 22. ALP2-Vorlesung, M. Esponda Inhalt 1. Einführung 2. Warum Bäume? 3. Listen und Arrays vs. Bäume 4. Einfach verkettete binäre Suchbäume
MehrWiederholung ADT Menge Ziel: Verwaltung (Finden, Einfügen, Entfernen) einer Menge von Elementen
Was bisher geschah abstrakter Datentyp : Signatur Σ und Axiome Φ z.b. ADT Menge zur Verwaltung (Finden, Einfügen, Entfernen) mehrerer Elemente desselben Typs Spezifikation einer Schnittstelle Konkreter
Mehr13. Binäre Suchbäume
1. Binäre Suchbäume Binäre Suchbäume realiesieren Wörterbücher. Sie unterstützen die Operationen 1. Einfügen (Insert) 2. Entfernen (Delete). Suchen (Search) 4. Maximum/Minimum-Suche 5. Vorgänger (Predecessor),
MehrBinärbäume: Beispiel
Binärbäume Als Beispiel für eine interessantere dynamische Datenstruktur sehen wir uns jetzt Binärbäume an Ein Binärbaum wird rekursiv definiert: Er ist leer oder besteht aus einem Knoten (die Wurzel des
Mehr3. Binäre Suchbäume. 3.1 Natürliche binäre Suchbäume. EADS 3.1 Natürliche binäre Suchbäume 78/598 ľernst W. Mayr
3. Binäre Suchbäume 3.1 Natürliche binäre Suchbäume Definition 18 Ein natürlicher binärer Suchbaum über einem durch total geordneten Universum U ist ein als interner Suchbaum organisierter Binärbaum (also:
MehrAlgorithmen und Datenstrukturen I AVL-Bäume
Algorithmen und Datenstrukturen I AVL-Bäume Prof. Dr. Oliver Braun Letzte Änderung: 01.12.2017 14:42 Algorithmen und Datenstrukturen I, AVL-Bäume 1/38 Balancierte Bäume in einem zufällig erzeugten Binärbaum
Mehr1. Einfach verkettete Liste unsortiert 2. Einfach verkettete Liste sortiert 3. Doppelt verkettete Liste sortiert
Inhalt Einführung 1. Arrays 1. Array unsortiert 2. Array sortiert 3. Heap 2. Listen 1. Einfach verkettete Liste unsortiert 2. Einfach verkettete Liste sortiert 3. Doppelt verkettete Liste sortiert 3. Bäume
MehrVerkettete Datenstrukturen: Bäume
Verkettete Datenstrukturen: Bäume 1 Graphen Gerichteter Graph: Menge von Knoten (= Elementen) + Menge von Kanten. Kante: Verbindung zwischen zwei Knoten k 1 k 2 = Paar von Knoten (k 1, k 2 ). Menge aller
MehrGrundlagen der Programmierung
Grundlagen der Programmierung Algorithmen und Datenstrukturen Die Inhalte der Vorlesung wurden primär auf Basis der angegebenen Literatur erstellt. Darüber hinaus wurden ausgewählte Teile in Abstimmung
MehrDatenstrukturen und Algorithmen
Datenstrukturen und Algorithmen VO 708.031 Bäume robert.legenstein@igi.tugraz.at 1 Inhalt der Vorlesung 1. Motivation, Einführung, Grundlagen 2. Algorithmische Grundprinzipien 3. Sortierverfahren 4. Halden
MehrFolge 19 - Bäume. 19.1 Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12
Grundlagen: Folge 19 - Bäume 19.1 Binärbäume - Allgemeines Unter Bäumen versteht man in der Informatik Datenstrukturen, bei denen jedes Element mindestens zwei Nachfolger hat. Bereits in der Folge 17 haben
Mehr3.8 Bäume. Definition des Baumes
3.8 Bäume Definition des Baumes Ein Baum besteht aus einer nichtleeren Menge von Knoten und einer Menge von Kanten. Jede Kante verbindet genau zwei Knoten. Die Knoten (nodes) enthalten Datenelemente. Die
MehrEinführung in die Informatik 2
Einführung in die Informatik 2 Listen & Bäume Sven Kosub AG Algorithmik/Theorie komplexer Systeme Universität Konstanz E 202 SvenKosub@uni-konstanzde Sprechstunde: Freitag, 14:00-15:00 Uhr, onv Sommersemester
MehrMotivation Binäre Suchbäume
Kap..: Binäre Suchbäume Professor Dr. Lehrstuhl für Algorithm Engineering, LS Fakultät für Informatik, TU Dortmund Zusätzliche Lernraumbetreuung Morteza Monemizadeh: Jeden Montag von :00 Uhr-:00 Uhr in
MehrDatenstrukturen. einfach verkettete Liste
einfach verkettete Liste speichert Daten in einer linearen Liste, in der jedes Element auf das nächste Element zeigt Jeder Knoten der Liste enthält beliebige Daten und einen Zeiger auf den nächsten Knoten
MehrMehrwegbäume Motivation
Mehrwegbäume Motivation Wir haben gute Strukturen (AVL-Bäume) kennen gelernt, die die Anzahl der Operationen begrenzen Was ist, wenn der Baum zu groß für den Hauptspeicher ist? Externe Datenspeicherung
MehrAlgorithmen und Datenstrukturen
Algorithmen und Datenstrukturen Dipl. Inform. Andreas Wilkens aw@awilkens.com Elementare Datenstrukturen Array Linked List Stack Queue Tree (Feld) (Verkettete Liste) (Stapel) (Warteschlange) (Baum) Einschub:
MehrDatenstrukturen & Algorithmen Lösungen zu Blatt 4 FS 15
Eidgenössische Technische Hochschule Zürich Ecole polytechnique fédérale de Zurich Politecnico federale di Zurigo Federal Institute of Technology at Zurich Institut für Theoretische Informatik 18. März
MehrVorlesung Informatik 2 Algorithmen und Datenstrukturen
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (23 Bruder-Bäume, B-Bäume) Prof. Dr. Susanne Albers Balancierte Bäume Eine Klasse von binären Suchbäumen ist balanciert, wenn jede der drei Wörterbuchoperationen
MehrInformatik Abitur Bayern 2017 / II - Lösung
Informatik Abitur Bayern 2017 / II - Lösung Autoren: Wolf (1) Wagner (2) Scharnagl (3-5) 1a 5 1b Diese Methode vergleicht den Namen des Interpreten eines jeden Elements der Liste mit dem gegebenen Namen.
MehrBäume, Suchbäume und Hash-Tabellen
Im folgenden Fokus auf Datenstrukturen, welche den assoziativen Zugriff (über einen bestimmten Wert als Suchkriterium) optimieren Bäume: Abbildung bzw. Vorberechnung von Entscheidungen während der Suche
Mehrt-äre Bäume können - wie Binärbäume - degenerieren, d.h. durch ungünstige Einfügereihenfolge kann ein unausgewogener Baum mit großer Höhe entstehen.
.3 B-Bäume t-äre Bäume können - wie Binärbäume - degenerieren, d.h. durch ungünstige Einfügereihenfolge kann ein unausgewogener Baum mit großer Höhe entstehen. Wird der t-äre Baum zur Verwaltung von Daten
Mehra) Fügen Sie die Zahlen 39, 38, 37 und 36 in folgenden (2, 3)-Baum ein:
1 Aufgabe 8.1 (P) (2, 3)-Baum a) Fügen Sie die Zahlen 39, 38, 37 und 36 in folgenden (2, 3)-Baum ein: Zeichnen Sie, was in jedem Schritt passiert. b) Löschen Sie die Zahlen 65, 70 und 100 aus folgendem
MehrAlgorithmen und Datenstrukturen
Algorithmen und Datenstrukturen Prof. Martin Lercher Institut für Informatik Heinrich-Heine-Universität Düsseldorf Teil 6 Suchbäume Version vom 25. November 2016 1 / 75 Vorlesung 10 22. November 2016 2
Mehr7. Sortieren Lernziele. 7. Sortieren
7. Sortieren Lernziele 7. Sortieren Lernziele: Die wichtigsten Sortierverfahren kennen und einsetzen können, Aufwand und weitere Eigenschaften der Sortierverfahren kennen, das Problemlösungsparadigma Teile-und-herrsche
MehrDefinition Ein Heap (priority queue) ist eine abstrakte Datenstruktur mit folgenden Kennzeichen:
HeapSort Allgemeines Sortieralgorithmen gehören zu den am häufigsten angewendeten Algorithmen in der Datenverarbeitung. Man hatte daher bereits früh ein großes Interesse an der Entwicklung möglichst effizienter
MehrBinäre Suchbäume. Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps
Binäre Suchbäume Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps Mengen n Ziel: Aufrechterhalten einer Menge (hier: ganzer Zahlen) unter folgenden Operationen: Mengen n Ziel: Aufrechterhalten einer
MehrBäume. Listen und Bäume, Graphen und Bäume, elementare Eigenschaften von Binärbäumen, Implementierung, Generische Baumdurchläufe
Bäume Listen und Bäume, Graphen und Bäume, elementare Eigenschaften von Binärbäumen, Implementierung, Generische Baumdurchläufe S. Staab, Informatik für IM II; Folien nach D. Saupe, sowie W. Küchlin, A.
MehrGliederung. 5. Compiler. 6. Sortieren und Suchen. 7. Graphen
5. Compiler Gliederung 1. Struktur eines Compilers 2. Syntaxanalyse durch rekursiven Abstieg 3. Ausnahmebehandlung 4. Arrays und Strings 6. Sortieren und Suchen 1. Grundlegende Datenstrukturen 2. Bäume
MehrContainerDatenstrukturen. Große Übung 4
ContainerDatenstrukturen Große Übung 4 Aufgabenstellung Verwalte Kollektion S von n Objekten Grundaufgaben: Iterieren/Auflistung Suche nach Objekt x mit Wert/Schlüssel k Füge ein Objekt x hinzu Entferne
MehrAlgorithmen und Datenstrukturen
Algorithmen und Datenstrukturen Binäre Bäume Zum Speichern und Suchen von Daten werden häufig Baumstrukturen verwendet Abspeichern von n Datenobjekten in einer Baumstruktur Ablegen von Daten ist in O(log(n))
MehrEinführung in die Informatik 2
Einführung in die Informatik 2 Bäume & Graphen Sven Kosub AG Algorithmik/Theorie komplexer Systeme Universität Konstanz http://www.inf.uni-konstanz.de/algo/lehre/ss08/info2 Sommersemester 2008 Sven Kosub
MehrKap. 4.2: Binäre Suchbäume
Kap. 4.2: Binäre Suchbäume Professor Dr. Lehrstuhl für Algorithm Engineering, LS11 Fakultät für Informatik, TU Dortmund 11. VO DAP2 SS 2009 26. Mai 2009 1 Zusätzliche Lernraumbetreuung Morteza Monemizadeh:
MehrÜbung Algorithmen und Datenstrukturen
Übung Algorithmen und Datenstrukturen Sommersemester 217 Patrick Schäfer, Humboldt-Universität zu Berlin Agenda: Graphen, Suchbäume, AVL Bäume Heute: Graphen und Bäume Binäre Suchbäume AVL-Bäume Nächste
MehrEinführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12. Kapitel 13. Bäume. Bäume
1 Kapitel 13 Ziele 2 Den Begriff des Baums in der Informatik kennenlernen als verkettete Datenstruktur repräsentieren können Rekursive Funktionen auf n verstehen und schreiben können Verschiedene Möglichkeiten
Mehrpublic interface Stack<E> { public void push(e e); public E pop();
ADS Zusammenfassung René Bernhardsgrütter 02.04.2012 1 Generics Gewähren Typsicherheit und können für verschiedene Datentypen ohne Casts verwendet werden. Beim Erstellen der Klasse werden Platzhalter für
MehrPunkte. Teil 1. Teil 2. Summe. 1. Zeigen Sie, dass der untenstehende Suchbaum die AVL-Bedingung verletzt und überführen Sie ihn in einen AVL-Baum.
Hochschule der Medien Prof Uwe Schulz 1 Februar 2007 Stuttgart Klausur Informatik 2, EDV-Nr 40303/42022 Seite 1 von 2 Name: Matr Nr: Teil 1: Keine Hilfsmittel Bearbeitungszeit: 20 Minuten Teil 1 Teil 2
MehrDatenstrukturen und Algorithmen
Datenstrukturen und Algorithmen VO INF.02031UF (2-4)-Bäume robert.legenstein@igi.tugraz.at 1 7. Bäume Bäume als Datenstruktur Binärbäume Balancierte Bäume (2-4)-Bäume Anwendung: Mischbare Warteschlangen
MehrAlgorithmen und Datenstrukturen Suchbaum
Algorithmen und Datenstrukturen Suchbaum Matthias Teschner Graphische Datenverarbeitung Institut für Informatik Universität Freiburg SS 12 Motivation Datenstruktur zur Repräsentation dynamischer Mengen
MehrDatenstrukturen & Algorithmen
Datenstrukturen & Algorithmen Matthias Zwicker Universität Bern Frühling 2010 Übersicht Binäre Suchbäume Einführung und Begriffe Binäre Suchbäume 2 Binäre Suchbäume Datenstruktur für dynamische Mengen
MehrEinführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung)
Wintersemester 2005/06 Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich Informatik Lehrstuhl
MehrTutorium Algorithmen & Datenstrukturen
June 16, 2010 Binärer Baum Binärer Baum enthält keine Knoten (NIL) besteht aus drei disjunkten Knotenmengen: einem Wurzelknoten, einem binären Baum als linken Unterbaum und einem binären Baum als rechten
MehrInformatik II Vorlesung am D-BAUG der ETH Zürich
Informatik II Vorlesung am D-BAUG der ETH Zürich Vorlesung 9, 2.5.2016 [Nachtrag zu Vorlesung : Numerische Integration, Zusammenfassung Objektorientierte Programmierung] Dynamische Datenstrukturen II:
MehrSuchbäume mit inneren Knoten verschiedener Knotengrade.
Was bisher geschah rekursive Datenstrukturen: lineare Datenstrukturen: Liste, Stack, Queue hierarchische Datenstrukturen: Bäume allgemeine Bäume Binäre Bäume Unäre Bäume = Listen Tiefe eines Knotens in
MehrAlgorithmen und Datenstrukturen Balancierte Suchbäume
Algorithmen und Datenstrukturen Balancierte Suchbäume Matthias Teschner Graphische Datenverarbeitung Institut für Informatik Universität Freiburg SS 12 Überblick Einführung Einfügen und Löschen Einfügen
MehrProgrammiertechnik II
Bäume Symboltabellen Suche nach Werten (items), die unter einem Schlüssel (key) gefunden werden können Bankkonten: Schlüssel ist Kontonummer Flugreservierung: Schlüssel ist Flugnummer, Reservierungsnummer,...
MehrAlgorithmen und Datenstrukturen 1
Algorithmen und Datenstrukturen 1 9. Vorlesung Peter Stadler Universität Leipzig Institut für Informatik studla@bioinf.uni-leipzig.de Balancierte Binärbäume Der ausgeglichene binäre Suchbaum verursacht
MehrVorlesung Informatik 2 Algorithmen und Datenstrukturen
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (21 - Balancierte Bäume, AVL-Bäume) Prof. Dr. Susanne Albers Balancierte Bäume Eine Klasse von binären Suchbäumen ist balanciert, wenn jede der drei
MehrStud.-Nummer: Datenstrukturen & Algorithmen Seite 1
Stud.-Nummer: Datenstrukturen & Algorithmen Seite 1 Aufgabe 1. / 16 P Instruktionen: 1) In dieser Aufgabe sollen Sie nur die Ergebnisse angeben. Diese können Sie direkt bei den Aufgaben notieren. 2) Sofern
MehrRotation. y T 3. Abbildung 3.10: Rotation nach rechts (analog links) Doppelrotation y
Die AVL-Eigenschaft soll bei Einfügungen und Streichungen erhalten bleiben. Dafür gibt es zwei mögliche Operationen: -1-2 Rotation Abbildung 3.1: Rotation nach rechts (analog links) -2 +1 z ±1 T 4 Doppelrotation
MehrALP II Dynamische Datenmengen Datenabstraktion (Teil 2)
ALP II Dynamische Datenmengen Datenabstraktion (Teil 2) O1 O2 O3 O4 SS 2012 Prof. Dr. Margarita Esponda 49 Einfach verkettete Listen O1 O2 O3 50 Einführung Einfach verkettete Listen sind die einfachsten
MehrAlgorithmen und Datenstrukturen I Bruder-Bäume
Algorithmen und Datenstrukturen I Bruder-Bäume Prof. Dr. Oliver Braun Letzte Änderung: 11.12.2017 10:50 Algorithmen und Datenstrukturen I, Bruder-Bäume 1/24 Definition ein binärer Baum heißt ein Bruder-Baum,
MehrAlgorithmen und Datenstrukturen
Algorithmen und Datenstrukturen Dynamische Datenobjekte Pointer/Zeiger, Verkettete Liste Eigene Typdefinitionen 1 Zeigeroperatoren & und * Ein Zeiger ist die Speicheradresse irgendeines Objektes. Eine
MehrAlgorithmik II. a) Fügen Sie in einen anfangs leeren binären Baum die Schlüsselfolge 20, 28, 35, 31, 9, 4, 13, 17, 37, 25 ein.
Aufgabe 10 Binäre Bäume a) Fügen Sie in einen anfangs leeren binären Baum die Schlüsselfolge, 28, 35, 31, 9, 4,, 17, 37, 25 ein. 1. Einfügen von : 3. Einfugen von 35: 2. Einfügen von 28: 28 28 10. Einfügen
MehrÜbung zur Vorlesung Algorithmische Geometrie
Übung zur Vorlesung Algorithmische Geometrie Dipl.-Math. Bastian Rieck Arbeitsgruppe Computergraphik und Visualisierung Interdisziplinäres Zentrum für Wissenschaftliches Rechnen 8. Mai 2012 B. Rieck (CoVis)
MehrDatenstrukturen. Mariano Zelke. Sommersemester 2012
Datenstrukturen Mariano Zelke Sommersemester 2012 Tiefensuche: Die globale Struktur Der gerichtete oder ungerichtete Graph G werde durch seine Adjazenzliste A repräsentiert. Im Array besucht wird vermerkt,
MehrSuchstrukturen. Übersicht. 8 Suchstrukturen. Allgemeines. H. Täubig (TUM) GAD SS
Übersicht 8 Suchstrukturen Allgemeines Binäre Suchbäume AVL-Bäume H. Täubig (TUM) GAD SS 14 309 Allgemeines Übersicht 8 Suchstrukturen Allgemeines Binäre Suchbäume AVL-Bäume H. Täubig (TUM) GAD SS 14 310
MehrMuster. Informatik 3 (Februar 2004) Name: Matrikelnummer: Betrachten Sie den folgenden Suchbaum. A G H J K M N
2 von 15 Aufgabe 1: Suchbäume (14 ) Betrachten Sie den folgenden Suchbaum. A B C D E F G H I J K L M N O P R (a) (1 Punkt ) Geben Sie die Höhe des Knotens F an. (b) (1 Punkt ) Geben Sie die Tiefe des Knotens
MehrVorlesung Datenstrukturen
Vorlesung Datenstrukturen Sortierte Folgen Maike Buchin 30.5., 1.6., 13.6.2017 Sortierte Folgen Häufiges Szenario: in einer Menge von Objekten mit Schlüsseln (aus geordnetem Universum) sollen Elemente
MehrGrundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny
Grundlagen der Informatik Prof. Dr. Stefan Enderle NTA Isny 2 Datenstrukturen 2.1 Einführung Syntax: Definition einer formalen Grammatik, um Regeln einer formalen Sprache (Programmiersprache) festzulegen.
MehrDatenstrukturen & Algorithmen Lösungen zu Blatt 6 FS 14
Eidgenössische Technische Hochschule Zürich Ecole polytechnique fédérale de Zurich Politecnico federale di Zurigo Federal Institute of Technology at Zurich Institut für Theoretische Informatik 2. April
MehrVorlesung Datenstrukturen
Vorlesung Datenstrukturen Heaps Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 469 Prioritätswarteschlange Problem Häufig ist das Prinzip einer einfachen Warteschlangen-Datenstruktur
MehrTeil 1: Suchen. Problemstellung Elementare Suchverfahren Hashverfahren Binäre Suchbäume Ausgeglichene Bäume. B-Bäume Digitale Suchbäume Heaps
Teil 1: Suchen Problemstellung Elementare Suchverfahren Hashverfahren Binäre Suchbäume Ausgeglichene Bäume AVL-Bäume Splay-Bäume B-Bäume Digitale Suchbäume Heaps M.O.Franz; Oktober 2007 Algorithmen und
MehrBäume, Anwendung und Begriffe
Bäume Sie wissen, was Bäume in der Informatik sind Sie kennen das Besucher-Entwurfsmuster Sie kennen Binärbäume Sie können die Bäume auf unterschiedliche Arten traversieren Sie wissen, wie man in Binärbäumen
Mehr