Bäume - Userpage

Werbung
15.06.2010
Bäume
O1
O2
O4
O3
O5
O6
O7
Prof. Dr. Margarita Esponda
Prof. Dr. Margarita Esponda
1
15.06.2010
Inhalt
1. Einführung
2. Warum Bäume?
3. Listen und Arrays vs. Bäume
4. Einfach verkettete binäre Bäume
Baumtraversierung
Suchen
Einfügen
5. Doppelt verkettete binäre Bäume
Löschen
Prof. Dr. Margarita Esponda
2
15.06.2010
Warum Bäume?
Bäume sind fundamentale
Datenstrukturen für:
Betriebssysteme
Datenbanken
Übersetzerbau
Textverarbeitung
Graphische Verarbeitung
Datenkompression
Spiele
… usw.
Prof. Dr. Margarita Esponda
3
15.06.2010
Was ist ein Baum?
Eine spezielle Graph-Struktur ohne Zyklen
root
1. Er hat eine Wurzel.
O1
2. Alle Knoten außer der Wurzel
haben genau eine Verbindung
O3
O2
mit einem Vorfahren.
O5
O4
O11
O7
3. Es existiert genau ein Weg
zwischen der Wurzel und
O10
O9
O8
O6
jedem beliebigen Knoten.
O12
Prof. Dr. Margarita Esponda
O13
O14
4
15.06.2010
Eigenschaften von Bäumen
•
Zwischen zwei beliebigen Knoten in einem Baum existiert
genau ein Pfad, der sie verbindet.
O1
Kanten
O3
O2
Knoten
O4
O8
•
O6
O5
O7
O9
O10
Ein Baum mit N Knoten hat N-1 Kanten.
Prof. Dr. Margarita Esponda
5
15.06.2010
Binärbäume
•
Bäume, in dem jeder Knoten höchstens zwei Kinder
hat.
•
Ein Binärbaum mit N inneren Knoten hat N+1 äußere
Knoten oder Blätter.
O5
Innere-Knoten
Blätter
Prof. Dr. Margarita Esponda
O10
O9
O11
O12
O13
O14
6
15.06.2010
Warum Bäume?
Weil die Grundoperationen für dynamische Datenmengen
damit viel effizienter realisiert werden können.
Suchen
Elementare Operationen
für dynamische Mengen
Einfügen
Löschen
Bäume kombinieren die Vorteile der zwei Datenstrukturen,
die wir bereits diskutiert haben: Felder (Arrays) und Listen.
Prof. Dr. Margarita Esponda
7
15.06.2010
Suchen
Sortiertes Array
Sortierte Liste
mit n Elementen
mit n Elementen
Kopf
Binärsuche
120
7
120
13
7
13
21
21
33
33
41
41
n/2
50
50
66
66
79
n/4
89
103
n/8
Schlimmster Fall
log2(n) Schritte
120
200
89
103
Schlimmster Fall
n Schritte
120
O(log2n)
Prof. Dr. Margarita Esponda
79
200
O(n)
8
15.06.2010
Einfüge- und Lösch-Operationen
( wenn die Position bereits bekannt ist )
Liste
Array
2
5
7
11
7
13
11
23
13
41
23
Die Laufzeit
hängt linear
von der Länge
der bereits
gespeicherten
Daten ab.
2
5
7
56
41
56
13
23
Schlimmster Fall
n Schritte
O(n)
Prof. Dr. Margarita Esponda
11
Die
Laufzeit
ist immer
konstant.
41
Schlimmster Fall
56
O(1)
9
15.06.2010
Liste vs. Array
Liste
Array
1
2
3
. . . . . . .
O1
O2
O3
1
2
3
O1
O2
O3
O4
O5
O6
n
O7
. . . . . . .
O4
O5
O6
O8
n
O7
O8
Elementare Operationen für dynamische Mengen
Liste
Schlimmster Fall
Suchen
n
Array
Schlimmster Fall
log2(n)
Einfügen
konstant + n
n + log2(n)
Löschen
konstant + n
n + log2(n)
Prof. Dr. Margarita Esponda
10
15.06.2010
Vollständige Binärbäume
Ein vollständiger binärer Baum hat 2h – 1 innere Knoten und 2h Blätter
n = 2h+1 - 1
root
⇓
Level 0
n + 1 = 2h+1
O1
⇓
Level 1
O2
O4
O3
O5
O6
h
O7
Level 2
log2(n+1) = log2(2h+1)
⇓
log2(n+1) = h+1
O8
O9
O10
O11
O12
O13
O14
O15Level 3
⇓
h = log2(n+1) -1
Prof. Dr. Margarita Esponda
11
15.06.2010
Binärbäume
Binärbäume
einfachste
Beispiele:
Baumstrukturen
AVL-Bäume
ausgeglichene Bäume
Red-Black-Bäume
B-Bäume
Die wichtigste Voraussetzung für die effiziente Verwaltung
von Datenmengen mit Hilfe von Bäumen ist, dass die Bäume
balanciert sind.
Prof. Dr. Margarita Esponda
12
15.06.2010
Binäre Suchbäume
geordneter Baum mit
O1
maximal 2 Nachfolgern
left right
pro Knoten
Innere
Knoten
O2
O3
left right
left right
O4
null
null
O5
null
null
O6
null
null
O7
null
null
Blätter
Prof. Dr. Margarita Esponda
13
15.06.2010
Wie können wir Binärbäume in Java
implementieren?
root
O3
left right
TreeNode-Klasse
BinarySearchTree-Klasse
O3
null
O3
right
left right
O3
left
Die Objekte werden
null
O3
null
null
nach einem Schlüssel
O3
einsortiert.
null
Prof. Dr. Margarita Esponda
null
14
15.06.2010
Einfach verkettete Binärsuchbäume, um Daten nach einem
Schlüsselwert zu speichern.
Sortierbare Schlüssel
eigentliche Daten
public class BinarySearchTree <T extends Comparable<T>, D>
implements Iterable<T> {
private TreeNode root;
private int size; // number of TreeNodes
um for-each-Schleifen
verwenden zu können
public BinarySearchTree() { // constructor
root = null;
size = 0;
}
public int size() {
return size;
}
…
Prof. Dr. Margarita Esponda
15
15.06.2010
Einfach verkettete Binärsuchbäume, um Daten nach einem
Schlüsselwert zu speichern.
public class BinarySearchTree ….
…
private class TreeNode {
private T key;
private D data;
private TreeNode left;
private TreeNode right;
TreeNode (T key, D data) {
this.key = key;
this.data = data;
size++;
}
}
…
Prof. Dr. Margarita Esponda
root
O3
left right
O3
O3
null right
left right
O3
left null
O3
null null
O3
null null
16
15.06.2010
Suchen
root
4
node
11
left right
7
19
left right
left right
3
left right
1
null
null
Prof. Dr. Margarita Esponda
null
left right
null
null
21
left right
left right
4
left right
14
9
12
null
null
left right
null
null
left right
null
null
17
15.06.2010
Suchen
root
4
node
11
left right
7
19
left
left right
left right
3
leftright
right
null
null
null
left right
null
null
21
left right
left right
4
1
left right
14
9
12
null
null
left right
null
null
left right
null
null
Wenn node gleich null wird, befindet sich das Element nicht in
dem Baum.
Prof. Dr. Margarita Esponda
18
15.06.2010
Einfach verkettete Binärsuchbäume, um Daten nach einem
Schlüsselwert zu speichern.
…
public boolean contains(T key) {
return getData( key ) != null;
}
Ein Schlüssel
wird gesucht
public D getData(T key) {
TreeNode node = root;
while (node != null) {
int compare = key.compareTo(node.key);
if (compare < 0)
node = node.left;
else if (compare > 0)
node = node.right;
else
Gibt die Daten, die mit
return node.data;
einem Schlüssel verbunden
}
sind, zurück oder null,
return null;
wenn der Schlüssel nicht
}
…
vorhanden ist.
Prof. Dr. Margarita Esponda
19
15.06.2010
Einfügen (iterativ)
root
6
x
y
11
xy
19
7
x
y
3
1
NULL
y
x
NULL
9
NULL
23
NULL
NULL
NULL
16
5
NULL
15
NULL
NULL
NULL
x
Prof. Dr. Margarita Esponda
20
15.06.2010
Einfach verkettete Binärsuchbäume, um Daten nach einem
Schlüsselwert zu speichern.
Ein Schlüssel und das damit verbundene
Daten-Objekt
werden
public class
BinarySearchTree
<T eingegeben
extends Comparable<T>, D>
implements Iterable<T> {
public void store(T key, D data) {
root = insert( root, key, data );
}
private TreeNode insert(TreeNode node, T key, D data) {
if (node == null)
return new TreeNode(key, data);
Ein neues Objekt
int compare = key.compareTo(node.key);
wird nach seinem
if (compare < 0)
Schlüssel in einem
node.left = insert(node.left, key, data); Blatt einsortiert.
}
else if (compare > 0)
node.right = insert(node.right, key, data);
else node.data = data;
Wenn der Schlüssel bereits
return node;
existiert, werden die Daten
…
überschrieben.
Prof. Dr. Margarita Esponda
21
15.06.2010
Traversierung binärer Bäume
Inorder
Linker Unterbaum - Wurzel - Rechter Unterbaum
F
D
B
A
I
E
J
G
C
H
A B C D E F G H I J
Prof. Dr. Margarita Esponda
22
15.06.2010
Implementierung einer Iterator-Klasse als Innere Klasse
public class BinarySearchTree <T extends Comparable<T>, D>
implements Iterable<T> {
…
public Iterator<T> iterator() {
return new InorderIterator();
}
Iterator-Klasse, die den
Baum in sortierter
Reihenfolge durchläuft.
private class InorderIterator implements Iterator<T> {
...
}
}
Prof. Dr. Margarita Esponda
23
15.06.2010
Iterative Implementierung
r
F
rr s t
x
s
Stapel
D
u
I
t
w
B
u
v
A
Prof. Dr. Margarita Esponda
E
C
z
y
J
G
q
H
24
15.06.2010
Iterative Implementierung
r
F
x
s
Stapel
D
rr s t
I
t
w
B
u
v
A
Prof. Dr. Margarita Esponda
E
C
z
y
J
G
q
H
25
15.06.2010
Iterative Implementierung
r
F
x
s
Stapel
D
rr s c
I
t
w
B
B
u
v
A
Prof. Dr. Margarita Esponda
E
C
z
y
J
G
q
H
26
15.06.2010
Iterative Implementierung
r
F
x
s
Stapel
D
rr s
I
t
w
B
B
u
v
A
Prof. Dr. Margarita Esponda
E
C
z
y
J
G
q
H
27
15.06.2010
Iterative Implementierung
r
F
x
s
Stapel
D
rr w
I
t
w
B
B
u
v
A
Prof. Dr. Margarita Esponda
E
C
z
y
J
G
q
H
28
15.06.2010
Iterative Implementierung
r
F
x
s
Stapel
D
rr
t
w
B
B
u
Prof. Dr. Margarita Esponda
E
E
v
A
I
C
z
y
J
G
q
H
29
15.06.2010
Iterative Implementierung
r
F
F
x
s
Stapel
D
rx y
t
w
B
B
u
Prof. Dr. Margarita Esponda
E
E
v
A
I
C
z
y
J
G
q
H
30
15.06.2010
Implementierung einer Iterator-Klasse als Innere Klasse
private class InorderIterator implements Iterator<T> {
private Stack<TreeNode> stack = new Stack<TreeNode>();
InorderIterator() { pushLeftTree(root); }
public boolean hasNext() { return !stack.isEmpty(); }
public T next() {
if (!hasNext()) throw new NoSuchElementException();
TreeNode node = stack.pop();
pushLeftTree(node.right);
return node.key;
}
public void pushLeftTree(TreeNode node) {
while (node != null) {
stack.push(node);
node = node.left;
}
}
public void remove() { throw new UnsupportedOperationException();}
}
Prof. Dr. Margarita Esponda
31
15.06.2010
Anwendungsbeispiel:
public static void main(String[] args) {
BinarySearchTree<Integer, String> st = new BinarySearchTree<Integer, String>();
st.store(43901, "Peter Meyer" );
st.store(43021, "Nils Meyer" );
st.store(43002, "Andre Meyer" );
st.store(43101, "Hans Meyer" );
st.store(43000, "Joachim Meyer" );
st.store(43501, "Carl Meyer" );
for(Iterator<Integer> iter = st.iterator(); iter.hasNext();)
System.out.println(iter.next());
System.out.println("size = " + st.size());
for (Integer s : st) {
System.out.println(s);
}
}
Prof. Dr. Margarita Esponda
32
15.06.2010
Minimum und Maximum
53
Minimum
27
13
Maximum
69
34
17
Prof. Dr. Margarita Esponda
63
Der erste
Knoten, der
keine linken
Kinder mehr
hat, beinhaltet
das kleinste
Element.
95
46
33
15.06.2010
Nachfolger
1. Fall
53
Es gibt einen
rechten Unterbaum.
Minimum
69
30
13
8
34
63
17
95
46
39
Prof. Dr. Margarita Esponda
34
15.06.2010
Nachfolger
2. Fall
53
Es gibt keinen
rechten Unterbaum.
69
30
13
8
34
63
17
46
95
Maximum
39
Wie können wir nach oben laufen?
Prof. Dr. Margarita Esponda
35
15.06.2010
Doppelt verkettete Bäume
y
53
parent
node
30
13
y
O3
69
node
y
34
left
63
right
95
node
8
17
46
39
Prof. Dr. Margarita Esponda
private class TreeNode {
private T key;
private D data;
private TreeNode left
private TreeNode right;
private TreeNode parent;
…
}
36
15.06.2010
Delete-Operation ( Löschen )
1. Fall
2. Fall
Löschen eines Knotens
ohne Kinder
Löschen eines Knotens
mit nur einem Kind
53
53
27
27
69
69
null
13
34
17
63
95
13
34
95
46
46
garbage
Prof. Dr. Margarita Esponda
63
garbage
37
15.06.2010
Löschen
3. Fall
Löschen eines Knotens mit zwei Kindern
Der Knoten, den man löschen möchte, wird durch
seinen Nachfolger ersetzt.
53
53
27
13
8
17
69
34
30
63
46
69
30
95
13
8
17
34
32
63
95
46
32
Der Nachfolger von 27 ist das Minimum des rechten Unterbaumes.
Das Minimum ist entweder ein Blatt oder hat maximal ein rechtes Kind.
Prof. Dr. Margarita Esponda
38
15.06.2010
Löschen
53
node
27
13
69
34
63
95
left
8
y
30
x
Prof. Dr. Margarita Esponda
46
parent
32
39
15.06.2010
Probleme mit einfachen binären Suchbäumen
balancierter Binärbaum
nicht
balancierter Binärbaum
53
53
27
13
69
34
17
30
63
46
83
30
95
95
59
139
71
65
77
60
62
Prof. Dr. Margarita Esponda
40
15.06.2010
Lösungen
AVL-Bäume
Red-Black-Bäume
AA-Bäume
B-Bäume
usw.
Innerhalb der insert- und delete-Operationen wird mit Hilfe von
Rotationen die Balance des Baumes ständig wiederhergestellt.
53
27
13
69
34
17
53
x
30
63
95
27
95
13
102
34
17
30
69
63
102
200
200
Prof. Dr. Margarita Esponda
41
15.06.2010
Elementare Operationen für dynamische Mengen
Liste
Schlimmster Fall
Array
Balancierter Binärbaum
Schlimmster Fall
Schlimmster Fall
Suchen
O(n)
O(log2(n))
O(log2(n))
Einfügen
O(n)
O(n)
O(log2(n))
Löschen
O(n)
O(n)
O(log2(n))
Prof. Dr. Margarita Esponda
42
Herunterladen