Bäume. Martin Wirsing. Ziele. Implementierung von Knoten. Bäume (abstrakt) Standardimplementierungen für Bäume kennen lernen

Ähnliche Dokumente
Bäume. Prof. Dr. Christian Böhm. in Zusammenarbeit mit Gefei Zhang. WS 07/08

Bäume. Martin Wirsing. Ziele. Baumknoten. Bäume - 2-dimensionale Listen. Standardimplementierungen für Bäume kennenlernen

Geordnete Binärbäume

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 16/17. Kapitel 14. Bäume. Bäume 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 17/18. Kapitel 14. Bäume. Bäume 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 15/16. Kapitel 13. Bäume. Bäume 1

7. Dynamische Datenstrukturen Bäume. Informatik II für Verkehrsingenieure

Listen. Prof. Dr. Christian Böhm. in Zusammenarbeit mit Gefei Zhang. WS 07/08

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12. Kapitel 13. Bäume. Bäume

Anwendungsbeispiel MinHeap

Suchbäume. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Tutoraufgabe 1 (Implementierung eines ADTs):

Wintersemester 2018/19. Kapitel 14: Bäume

Software Entwicklung 1

Kapitel 12: Induktive

Tutoraufgabe 1 (Implementierung eines ADTs):

Tutoraufgabe 1 (Implementierung eines ADTs):

Software Entwicklung 1

Vorlesung Datenstrukturen

B6.1 Introduction. Algorithmen und Datenstrukturen. Algorithmen und Datenstrukturen. B6.1 Introduction. B6.3 Analyse. B6.4 Ordnungsbasierte Methoden

Städtisches Gymnasium Olpe Java Ht Informatik - Q1 Die Klasse List im Abitur Methoden und Beispielcode Hier alle wichtigen Methoden. Ein Beispielcode

Trees. November 14, Algorithms & Datastructures 2 Exercises WT 2017

Bäume 1. Thomas Röfer

Trees. November 13, Algorithms & Datastructures 2 Exercises WT 2017

Grundlagen der Informatik / Algorithmen und Datenstrukturen. Aufgabe 132

Semestralklausur Informatik I - Programmierung

Aufgabe 1 (Programmanalyse, Punkte)

Binäre Suchbäume. Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps

Institut für Programmierung und Reaktive Systeme 17. Juli Programmieren II. Übungsklausur

12 Abstrakte Klassen, finale Klassen und Interfaces

Datenstruktur Baum Software Entwicklung 1

13. Dynamische Datenstrukturen

Übung 4: Die generische Klasse AvlBaum in Java 1

Datenstrukturen Teil 2. Bäume. Definition. Definition. Definition. Bäume sind verallgemeinerte Listen. Sie sind weiter spezielle Graphen

Datenstruktur Baum und Rekursion Software Entwicklung 1

Informatik II, SS 2014

Universität Augsburg, Institut für Informatik Sommersemester 2001 Prof. Dr. Martin Ester 16. Juli Klausur

Informatik II Vorlesung am D-BAUG der ETH Zürich

Abiturprüfung Informatik, Grundkurs

13. Bäume: effektives Suchen und Sortieren

Einführung Elementare Datenstrukturen. Der Konstruktor muß den Listenkopf head erzeugen. Der Vorgänger und Nachfolger von head ist head selbst.

Vorlesung Informatik 2 Algorithmen und Datenstrukturen

13. Bäume: effektives Suchen und Sortieren

18. Natürliche Suchbäume

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 16/17. Kapitel 13. Listen. Listen 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 15/16. Kapitel 12. Listen. Listen 1

4.4.1 Implementierung vollständiger Bäume mit Feldern. Reguläre Struktur: Nachfolger des Knoten i sind die Knoten 2*i und 2*i+1.

Algorithmen und Datenstrukturen. Algorithmen und Datenstrukturen. B6.1 Einführung. B6.2 Symboltabellen. B6.3 Einfache Implementationen

Physikalisch Technische Lehranstalt Wedel 31. Januar 2004 Prof. Dr. Uwe Schmidt

3 Dynamische Datenstrukturen

18. Natürliche Suchbäume

Suchen und Sortieren

Grundlagen der Informatik / Algorithmen und Datenstrukturen. Aufgabe 143

Allgemeine Hinweise:

Fachhochschule Wedel 31. Januar 2004 Prof. Dr. Uwe Schmidt

Mengen. Binäre Suchbäume. Mengen: Anwendungen (II) Mengen: Lösung mit Listen 12/3/12. Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps

Datenstrukturen sind neben Algorithmen weitere wichtige Bausteine in der Informatik

Dokumentation zum AVL-Baum (C++)

5.14 Generics. Xiaoyi Jiang Informatik I Grundlagen der Programmierung

Einführung in die Informatik 2

16. Dynamische Datenstrukturen

Schnittstellen, Stack und Queue

Software Entwicklung 1. Fallstudie: Arithmetische Ausdrücke. Rekursive Klassen. Überblick. Annette Bieniusa / Arnd Poetzsch-Heffter

9. Natürliche Suchbäume

Binärbäume: Beispiel

Bäume. Text. Prof. Dr. Margarita Esponda SS 2012 O4 O5 O6 O ALP2-Vorlesung, M. Esponda

14 Abstrakte Klassen, finale Klassen, Interfaces

Objektorientierte Programmierung

Allgemeine Hinweise:

14 Abstrakte Klassen, finale Klassen, Interfaces. Auswertung von Ausdrücken. Beispiel. Abstrakte Methoden und Klassen

Abstrakte Klassen und Induktive Datenbereiche

Vorlesung Informatik 2 Algorithmen und Datenstrukturen

Tutoraufgabe 1 (2 3 4 Bäume):

14 Abstrakte Klassen, finale Klassen, Interfaces

Software Entwicklung 1

Probeklausur zur Vorlesung

Wiederholungsblatt Einführung in die Programmierung Lösungen

Datenstrukturen. Mariano Zelke. Sommersemester 2012

Die objektorientierte Mühle Marc-Oliver Pahl

Konstruktor BinaryTree() Nach dem Aufruf des Konstruktors existiert ein leerer Binärbaum.

Informatik II - Übung 07

Informatik Abitur Bayern 2017 / II - Lösung

Wiederholung. Bäume sind zyklenfrei. Rekursive Definition: Baum = Wurzelknoten + disjunkte Menge von Kindbäumen.

Algorithmen und Datenstrukturen

Verkettete Datenstrukturen: Bäume

Übersicht. Einfache Suche. Hashing Skip-Lists Mengen Sortieren Order-Statistics. 2 Suchen und Sortieren

Informatik II, SS 2016

Prof. Dr. Uwe Schmidt. 30. Januar 2017

Objektorientierte Programmierung

Lösungshinweise/-vorschläge zum Übungsblatt 8: Software-Entwicklung 1 (WS 2017/18)

Transkript:

2 Ziele Bäume Standardimplementierungen für Bäume kennen lernen Martin Wirsing in Zusammenarbeit mit Michael Barth, Philipp Meier und Gefei Zhang 02/0 4 Bäume (abstrakt) Implementierung von Knoten Bäume sind hierarchische Strukturen. Bäume bestehen aus Knoten und Teilbäumen. Der oberste Knoten heißt Wurzel. Bei Binärbäumen hat jeder Knoten zwei Unterbäume: den linken Unterbaum, den rechten Unterbaum. In den Knoten kann Information gespeichert werden. Linker Teilbaum Wurzel- Knoten Knoten Rechter Teilbaum { Node left; int key; Object value Node right; o1 Ein Knoten wird implementiert als Objekt mit zwei Zeigern. Außerdem wird in jedem Knoten ein Schlüssel und ein Wert gespeichert. o 9 o2

Implementierung von Bäumen public class BinTree { Node anchor; { Node left; int key; Object value; Node right; // Konstruktor Node(Node b1, int k, Object o, Node b2) { left = b1; key = k; value = o; right = b2; Ein Baum wird implementiert durch einen Zeiger auf ein Geflecht von Knoten: Die Klasse BinTree hat wie List einen Anker, der auf Node zeigt. Die Klasse Node ist eine Hilfsklasse für die Klasse BinTree. Ein Beispiel für eine Instanz von BinTree : BinTree anchor o1 class BinTree { Node anchor; Eine Bauminstanz zeigt auf eine Nodeinstanz o 9 o2 Konstruktoren BinTree() der leere Baum BinTree(B 1, k,o, B 2 ) neuer BinTree mit linkem Teilbaum B 1 rechtem Teilbaum B 2 Inhalt der Wurzel: k,o Operationen auf BinTree Prädikat isempty Testen, ob ein BinTree leer ist Selektoren getleft, getright, getkey Falls der BinTree nicht leer ist, liefert getleft() den linken Teilbaum getright() den rechten Teilbaum getkey() den Inhalt der Wurzel B 1 B 2 boolean BinTree int Object BinTree BinTree in UML + BinTree anchor Node isempty() 0..1 int key Object value getleft() getkey() int getkey() getvalue() Object getvalue() getright() Node getleft() Node getright() void setkey(int k) void setvalue(object o) void setleft(node l) void setright(node l) left, right 0..1

Implementierung in Java Die Implementierung von BinTree verläuft analog zu Listen: BinTree repräsentiert Binärbäume über einem Integer-Schlüssel und Werten vom Typ Object. BinTree selbst speichert nur einen Verweis auf die Wurzel des Baumes. Die eigentliche Funktionalität wird von der Klasse Node realisiert; 9 Implementierung BinTree: isempty & Zugriff auf linken Teilbaum public class BinTree { private Node anchor; Implementierung verläuft analog zu Listen BinTree(){; // der leere Baum BinTree(BinTree b1, int k, Object o, BinTree b2) { anchor = new Node(b1.anchor, k, o, b2.anchor); 10 Um Funktionen auf BinTree zu definieren, verwenden wir folgende Fallunterscheidung: leerer Baum: Berechnung des Resultats direkt in BinTree nicht-leerer Baum: Weitergeben ( delegieren ) der Funktion an Node boolean isempty(){return anchor==null; BinTree getleft() throws NoSuchElementException { if (anchor == null) throw new NoSuchElementException(); else { BinTree l = new BinTree(); l.anchor = anchor.getleft(); return l; 11 Anzahl der Knoten Prinzipieller Ablauf der (rekursiven) Berechnung von t.sumnodes(): 1. Berechne die Anzahl der Knoten suml des linken Teilbaums; 2. Berechne die Anzahl der Knoten sumr des rechten Teilbaums;. Gesamtanzahl der Knoten: 1 + suml +sumr. 10 Keller Halde Anzahl der Knoten (Implementierung)... t:... t.anchor suml = sumr = 2 Ergebnis = 1 + suml +sumr =

Anzahl der Knoten (Implementierung)... t: t.sumnodes():... 1. Wenn t nicht leer, delegiere die Aufgabe an Node durch Aufruf von anchor.sumnodes(); 2. Sei suml = Anzahl Knoten des linken Kindknotens;. Sei sumr = Anzahl Knoten des rechten Kindknotens; 4. Ergebnis: 1 + suml +sumr t.anchor 1 where Implementierung BinTree: Anzahl der Knoten int sumnodes() { if (anchor == null) return 0; else return anchor.sumnodes(); Delegieren der Aufgabe an { sumnodes() (aus der int sumnodes() Klasse Node) { int suml = 0, sumr = 0; if (left!= null) suml = left.sumnodes(); if (right!= null) sumr = right.sumnodes(); return 1 + suml + sumr; 14 Wenn der Baum leer ist, gibt es keinen Knoten; d.h. Anzahl = 0 suml = sumr = 2 Ergebnis = 1 + suml +sumr = 1 1 Geordnete Binärbäume Geordnete Binärbäume Ein Binärbaum b heißt geordnet, wenn folgendes für alle nichtleeren Teilbäume t von b gilt: Der Schlüssel von t ist größer (oder gleich) als alle Schlüssel des linken Teilbaums von t und Beispiel: Geordnet sind: Der leere Baum und der Baum t: t = (abstrakte Darstellung) kleiner (oder gleich) als alle Schlüssel des rechten Teilbaums von t Nicht geordnet ist der Baum t1: t1 = 9

1 1 Prinzipieller Ablauf der Berechnung von t.find(): Prinzipieller Ablauf der Berechnung von t.find(): 1. Vergleiche mit dem Wert der Wurzel; 2. Da <, gehe zum linken Kindknoten; < 1. Vergleiche mit dem Wert der Wurzel; 2. Da <, gehe zum linken Kindknoten;. Vergleiche mit dem Wert dieses Knotens; 4. Da >, gehe zum rechten Kindknoten dieses Knotens; < > Prinzipieller Ablauf der Berechnung von t.find(): 1. Vergleiche mit dem Wert der Wurzel; 2. Da <, gehe zum linken Kindknoten; <. Vergleiche mit dem Wert dieses Knotens; 4. Da >, gehe zum rechten Kindknoten dieses Knotens; >. Vergleiche mit dem Wert dieses Knotens;. Da ==, gebe Ergebnis true zurück. 19 == return true; (Implementierung) t t.find(): 1. Suche zunächst in BinTree. 2. Wenn t nicht leer, delegiere die Aufgabe an Node durch Aufruf von anchor.find();. Verfahre wie auf den vorgehenden Folien. < > == return true t.anchor 20

21 22 public Object find(int key) { if (anchor == null) return false; else return anchor.find(key); wobei Gibt true zurück, wenn key im Baum; sonst wird false zurückgegeben public Object findvalue(int key) { if (anchor == null) return null; else return anchor.find(key); wobei Gibt value zurück, wenn key im Baum; sonst wird null zurückgegeben { Object find (int key) { Node current = ; while(current.key!= key) // solange nicht gefunden, { if(key < current.key) // gehe nach links? current = current.left; else current = current.right; if(current == null) return false; //nicht gefunden! return true; // sonst gehe nach rechts //gefunden; gib true zurück { Object findvalue(int key) { Node current = ; while(current.key!= key) // solange nicht gefunden, { if(key < current.key) // gehe nach links? current = current.left; else current = current.right; if(current == null) return null; //nicht gefunden! return current.value; // sonst gehe nach rechts //gefunden; gib value zurück Einfügen in geordneten Binärbaum Beim Einfügen in einen geordneten Binärbaum wird rekursiv die richtige Stelle gesucht, so dass wieder eine geordneter Binärbaum entsteht. Beispiel: t.insert() ergibt: (Zur Vereinfachung der Darstellung wird hier nur ein Schlüssel und kein Wert eingefügt.) t = t = 10 t.insert() 10 2 t t.insert() Aufruf von t.insertkey(id): 24

t t.insert() 2 t anchor.insertkey(): 2 Delegieren der Aufgabe durch Aufruf von anchor.insertkey(id): Delegieren Delegieren der der Aufgabe Aufgabe durch durch Aufruf Aufruf von von anchor.insertkey(id): anchor.insertkey(id): Durchlauf durch das Node-Geflecht mit zwei Hilfsvariablen current und parent t anchor.insertkey(): current parent 2 Falls id > current.key, gehe nach Setze rechts: if(id > current current.key) = ; current parent = current.right; = current; anchor.insertkey(): current current parent 2 Und Falls setze: id > current.key, parent gehe nach = current; rechts: if(id > current.key) current = current.right; Delegieren der Aufgabe durch Aufruf von anchor.insertkey(id): Durchlauf durch das Node-Geflecht mit zwei Hilfsvariablen current und parent

anchor.insertkey(): current current parent Und Falls setze: id < current.key, parent gehe nach= links: current; if(id < current.key) current = current.left; 29 anchor.insertkey(): current current null parent Wenn current= null, füge neuen Knoten ein: if(current Falls id == < null) current.key, { parent.left gehe nach links: if(id = new< Node(null,id,null); current.key) return current ; = current.left; 0 anchor.insertkey(): current current null parent Wenn current= null, füge neuen Knoten ein: if(current == null) { parent.left = new Node(null,id,null); return ; 1 Einfügen in geordneten Binärbaum public void insert(int id, Object o) { if(anchor==null) // falls kein Knoten im anchor anchor = new Node(null, id,o, null); // neuer Knoten else anchor = anchor.insertkeyobj(id, o); wobei insertkeyobj in folgendermaßen definiert wird: Fügt einen neuen Knoten mit Schlüssel id an der richtigen Stelle im geordneten Baum ein 2

Node insertkeyobj(int id, Object o) Fügt einen neuen { Node current = ; // starte bei Knoten passend ein Node parent; Achtung:id darf nicht while(true) // terminiert intern im Baum vorkommen! { parent = current; if(id < current.key) // gehe nach links? { current = current.left; if(current == null) // am Ende füge links ein { parent.left = new Node(null, id, o, null); return ; // end if go left else // falls id > current.key, gehe nach rechts { current = current.right; if(current == null) // am Ende füge rechts ein { parent.right = new Node(null, id, o, null); return ; // end else go right // end while Rekursion auf Binärbäumen Binärbäume sind induktiv definiert Der Leere Baum ist ein Binärbaum BinTree(B 1, k,o, B 2 ) Sind B 1 und B 2 Binärbäume, id ein Schlüssel und o ein Objekt, dann ist der Baum mit Wurzel id und o, linkem Teilbaum B1 und rechtem Teilbaum B 2 ein Binärbaum Operationen f auf Binärbäumen können rekursiv definiert werden Falls isempty(b): gibt f(b) direkt an Ansonsten beschreibe wie sich der Wert von f aus f(b 1 ), 1 f(b 2 ) und id,o ergibt. Beispiel: sumnodes1() Falls isempty(b): 0 Ansonsten getleft().sumnodes1()+getright().sumnodes1()+1 Beispiel: exist(int k) (ist k vorhanden?) Falls isempty(b) : false Ansonsten: getleft().exists(k) getkey()==k getright().exists(k) 2 4 4 sumnodes: 9 Einfache Baumoperationen public class XBinTree extends BinTree { public int sumnodes() { if(isempty()) return 0; else return ((XBinTree)getLeft()).sumNodes() + ((XBinTree)getRight()).sumNodes() +1; public boolean exists(int k) { if(isempty()) return false; else return ((XBinTree)getLeft()).exists(k) getkey()==k ((XBinTree)getRight()).exists(k); isempty(), left(), right() werden aus der Oberklasse geerbt left() liefert einen BinTree sumnodes() ist nur in der Unterklasse definiert - für XBinTrees Wir brauchen casts um die BinTrees in XBinTrees zu verwandeln Zusammenfassung Binäre Bäume werden in Java implementiert: als Verallgemeinerung der einfach verketteten Listen mit zwei Nachfolgerverweisen Eine Operation auf binären Bäume mit Knoten wird definiert: durch Weitergeben der Operation an die Knotenklasse oder durch Fallunterscheidung bzgl. des leeren Baums und rekursiven Aufruf der Selektoren getleft() und getright() von BinTree.