 
                                Gliederung
5. Compiler
1.
2.
3.
4.
Struktur eines Compilers
Syntaxanalyse durch rekursiven Abstieg
Ausnahmebehandlung
Arrays und Strings
6. Sortieren und Suchen
1.
2.
3.
4.
5.
Grundlegende Datenstrukturen
Bäume
B-Bäume und Tries
Sortieren in Vektoren
Streuspeicherung
7. Graphen
1. Darstellung und Topologisches Sortieren
2. Kürzeste Wege
3. Fluß- und Zuordnungsprobleme
Bäume
• Bäume gehören zu den fundamentalen Datenstrukturen der
Informatik
• Bäume können als zweidimensionale Verallgemeinerung von
Listen aufgefasst werden
• In Bäumen können zusätzlich zu Daten auch relevante
Beziehungen der Daten untereinander (z.B. Ordnungsoder hierarchische Beziehungen) gespeichert werden
• Aufgrund ihrer Struktur eignen sich Bäume besonders gut
dazu, gesuchte Daten rasch wieder aufzufinden.
2
Beispiele von Bäumen
• Beispiele von Bäume
– Stammbäume
– Systematik in der Biologie
– Dateibäume
3
Bäume: Grundbegriffe (1)
• Ein Baum ist eine Menge von Knoten (dargestellt als Punkte,
Kreise, Rechtecken, ...), die miteinander durch Kanten
(dargestellt als Pfeile) verbunden sind
• Führt von Knoten A zu Knoten B eine Kante, sagt man:
A ist Vater von B bzw. Vorgänger von B
B ist Sohn von A bzw. Vorgänger von A
• Ein Pfad von A nach B ist eine Folge von Knoten und Pfeilen,
die von A nach B führen: A → X1→ X2→ X3→ X4......B
• Die Länge eines Pfades wird als Anzahl der Knoten in diesem
Pfad definiert
• Gibt es ein Pfad von A nach B, so heißt A ein Vorfahre von B
und B ein Nachkomme von A
4
Bäume: Grundbegriffe (2)
• Bäume müssen folgende Axiome erfüllen
– Es gibt genau einen Knoten ohne Vater: die Wurzel
– Jeder anderer Knoten hat genau einen Vater
• Daraus folgt:
– Es gibt keinen zyklischen Pfad
– Von der Wurzel aus gibt es zu jedem Knoten genau einen Pfad
– Die Nachkommen eines beliebigen Knotens K zusammen mit allen
Kanten bilden einen Baum mit K als Wurzel, den Unterbaum mit
Wurzel K
5
Bäume: Grundbegriffe (3)
• Die Länge des Pfades von der Wurzel zu einem Knoten wird
die Tiefe eines Knoten benannt
• Die Tiefe eines Baumes ist das Maximum der Tiefe seiner
Knoten
• Der Grad eines Knotens K g(K) ist gleich der Anzahl der
Nachfolger von K
– Ein Knoten ohne Nachfolger (g(K) =0) wird Blatt genannt, sonst wird
er innerer Knoten genannt
• Der Grad g(B) eines Baumes ist gleich dem maximalen
Grad seiner Knoten
6
Bäume: Grundbegriffe (4)
Rekursive Definition:
Ein Baum ist leer oder er besteht aus einer Wurzel W und
einer leeren oder nichtleeren Liste B1, B2, ..., Bn von Bäumen.
Von W zur Wurzel Wi von Bi führt jeweils eine Kante
W
W1
W2
...........
Wn
7
Bäume: Beispiel
• Baum der Tiefe 4
• (W, A, E, K ) ist ein Pfad der Länge 4
W
Kante
A
Wurzel
I
Innerer Knoten
E
K
Ein Blatt der Tiefe 4
8
Binärbäume
• Definition: Ein Binärbaum ist ein Baum vom Grad ≤ 2, d.h. er ist
entweder leer oder er besteht
– aus einem Knoten (Wurzel) und
– zwei mit der Wurzel verbundenen Binärbäumen, dem linken und rechten
Teilbaum.
• Ein Binärbaum der Tiefe T hat höchstens 2T-1 viele Knoten (Beweis über
Induktion)
Linker Teilbaum
Rechter Teilbaum
9
Binärbäume: anwendbare Operationen
•
•
•
•
empty : Baum → boolean liefert true, falls Baum leer ist
left : Baum → Baum liefert linken Teilbaum
right : Baum → Baum liefert rechten Teilbaum
value : Baum → Objekt liefert die Wurzel des Baumes
10
Binärbäume: Implementierung (1)
• Jeder Knoten ist wiederum die Wurzel eines Teilbaumes
• Der Wurzelknoten muss verwaltet werden, alle andere
Knoten sind durch verfolgen der Verweise erreichbar
Inhalt
public class TreeNode {
Object inhalt;
TreeNode left = null,
TreeNode right = null;
}
Links
Rechts
Inhalt
Links
Inhalt
Links
Rechts
Rechts
Inhalt
Links
Rechts
11
Binärbäume: Implementierung (2)
public class TreeNode {
Object elem;
TreeNode left = null, right = null;
public TreeNode (Object e) { elem = e; }
public TreeNode getLeft () { return left; }
public TreeNode getRight () { return right; }
public Object getElement () { return elem; }
public void setLeft (TreeNode n) { left = n; }
public void setRight (TreeNode n) { right = n; }
public boolean isLeaf () {
return left == null && right == null;
}
}
public Class BinaryTree{
protected TreeNode root =null
public BinaryTree(){}
public BinaryTree(TreeNode n){ root = n;}
..............
}
12
Darstellung arithmetischer Ausdrücken mit Binärbäumen
• Die inneren Knoten enthalten
die Operatoren, die Blätter
enthalten die (einfachen)
Operanden
• Einstellige Operatoren werden
als Knoten mit nur einem
Nachfolger repräsentiert
• In der Baumdarstellung sind
Klammern und Präzedenzregeln
überflüssig
-
12
9
*
!
3
-
7
12 - ( 3 * (7 - 5 ) ! - 9 )
5
13
Traversierung von Bäumen (1)
• Einen Baum zu durchlaufen bedeutet, alle seine Knoten in
einer bestimmten Reihenfolge zu besuchen. Dabei können
auf die Daten im jeweiligen Knoten spezielle Operationen
angewandt werden.
• Für das Durchlaufen (traversal) von Bäumen können
verschiedene Reihenfolgen festgelegt werden, in denen die
einzelnen Knoten zu besuchen sind:
–
–
–
–
Inorder
Preorder
Postorder
Levelorder
14
• Inorder
Traversierung von Bäumen (2)
– Besuche rekursiv den linken Teilbaum
– Besuche die Wurzel
– Besuche rekursiv den rechten Teilbau
D->B->E->A->F->C->G
A
• Preorder
– Besuche die Wurzel
– Besuche rekursiv den linken Teilbaum
– Besuche rekursiv den rechten Teilbaum
A->B->D->E->C->F->G
• Postorder
C
B
D
E
F
G
– Besuche rekursiv linken Teilbaum
– Besuche rekursiv den rechten Teilbaum
– Besuche die Wurzel
D->E->B->F->G->C->A
Merke: Postorder liefert eine Postfix-Notation für arithmetische Ausdrücke!
• Levelorder: Besuche die Knoten schichtenweise
– Zuerst die Wurzel
– Dann die Nachfolger
– Dann die Nächste Ebene
A->B ->C->D->E ->F->G
15
Suchbäume
• Ein Suchbaum ist ein Baum, auf dessen Daten (meistens
mittels eines Schlüssels) eine Ordnungsrelation definiert ist
• Ein binärer Suchbaum ist ein Binärbaum mit folgenden
Eigenschaften:
– Alle Knoten k haben einen Schlüsselwert s(k)
– Ist w ein innerer Knoten und sind TL und TR der linke bzw. rechte
Nachfolger von w, so gilt:
s(kL) ≤ s(w) < s(kR) für alle Knoten kL von TL und kR von TR
16
Binäre Suchbäume
w
Alle Elemente
im linken
Teilbaum sind ≤ w
•
•
Alle Elemente
im rechten
Teilbaum sind > w
Auf den Schlüsseln der Elemente muss eine totale Ordnung definiert sein
Sortierungseingenschaft: Die Daten in einem binären Suchbaum sind in
17
Inorder-Reihenfolge immer korrekt sortiert!
Suchen in binären Suchbäumen
• Suche nach Element x:
– Vergleichen mit der Wurzel, falls x=w: Element gefunden
– Falls x ≤ w , suche im linken Teilbaum weiter
– Falls x > w suche im rechten Teilbaum
• Suchalgorithmus: Pseudo-Code
BinTreeSearch(k,x)
– Eingabe: Wurzel k des zu durchsuchenden Teilbaumes
– Ausgaben: Element mit dem gesuchten Wert bzw. null, wenn x nicht
gefunden wurde
if k=null then return null;
Else if x =k.key then return k;
Else if x< k.key then return BinTreeSearch(k.left,x)
Else return BinTreeSearch(k.right,x)
18
Minimale und maximales Element
• Minimales Element: die kleineren Elemente sind immer die
linken Nachfolger eines Knotens: Das minimale Element
muss sich ganz links im Baum befinden
• Maximales Element: die größeren Elemente sind immer die
rechten Nachfolger eines Knotens: Das maximale Element
muss sich ganz rechts im Baum befinden
Minimum
while k.left != null do
k:= k.left
od
return k
Maximum
While k.right != null do
k:= k.right
od
Return k
19
Implementierung: Elemente von Suchbäumen
• Die Elemente von binären Suchbäumen müssen untereinander
vergleichbar sein.
• Die Vergleichbarkeit wird durch die Implementierung der JavaSchnittstelle Comparable erreicht: Für die abstrakte Methode
• public abs t r a c t int compareTo ( Objec t o )
muss eine konkrete Implementierung bereitgestellt werden: liefert einen
negativen Wert, Null oder einen positiven Wert zurück, je nachdem, ob
das aktuelle Objekt kleiner als o, gleich o oder größer ist.
• Beispiel:
class TreeElem implements Comparable {
String inhalt;
Elem (String x) { inhalt = x; }
public int compareTo (Object o) {
Elem e = (Elem) o;
return inhalt.compareTo(e.inhalt);
}
Verwendung der in
String definierte
compareTo-Methode
20
Einfügen in binären Suchbäumen
• Korrekte Einfügeposition
– Knoten, dessen Schlüsselwert größer
als der des einzufügenden Knoten ist
und noch keinen linken Nachfolger
hat
– Knoten, dessen Schlüsselwert kleiner
als der des einzufügenden Knoten
und noch keinen rechten Nachfolger
hat
6
9
3
5
1
7
10
• Mögliche Fälle
– Baum ist leer: Der einzufügende
Knoten ist wird die Wurzel des
Baumes
– Baum enthält bereits Knoten: Knoten
identifizieren, der Elternknoten des
neuen Elementes werden soll
4
Einfügen von 4
21
Löschen aus binären Suchbäumen (1)
• Beim Entfernen eines inneren Knotens muss einer der
Teilbäume hochgezogen und u.U. umgeordnet werden!
• Mögliche Fälle
– Der zu entfernende Knoten k ist ein Blatt: Der Knoten kann einfach
abgetrennt werden (Dies ist der einfachste Fall)
– Der zu entfernende Knoten k besitzt einen Kindknoten: Verweis vom
Elternknoten von k muss auf den Kindknoten von k umgelenkt
werden
– Der zu entfernende Knoten ist ein innerer Knoten mit zwei
Kindknoten
• Der Knoten mit dem nachfolgenden Schlüsselwert muss aus seiner
bisherigen Position entfernt werden und an die Stelle von k kopiert
werden
• Merke: Der Knoten mit dem kleinsten Element des rechten Teilbaumes
von k ist der Nachfolger (Schlüsselwert) von k und besitzt keinen linken
Teilbaum
22
Löschen aus binären Suchbäumen (2)
6
6
9
3
5
1
7
Element 5 löschen
3
9
10
1
4
7
10
4
23
Löschen aus binären Suchbäumen (3)
6
6
9
3
5
1
left
4
7
Element 3 löschen
4
10
1
9
5
7
10
right
24
Löschen aus binären Suchbäumen (4)
6
7
9
4
1
5
7
Element 6 löschen
9
4
10
1
5
10
25
Komplexität der Operationen in binären Suchbäumen
• Der Aufwand der Operationen hängt ausschließlich von der
Tiefe des Baumes ab, d.h. O(t) für ein Baum der Tiefe t
• Problem: Bestimmte Einfügereihenfolgen können zu
entarteten Bäumen führen
Eingabe: 1,3,5,6,7,9,10
1
Eingabe: 6,3,9,1,5,7,10
3
5
6
6
9
3
7
9
1
5
7
10
10
26