Graphen, Bäume, Halden

Werbung
Modul: Programmierung B-PRG
Grundlagen der Programmierung 1 – Teil 1 – V10
Graphen, Bäume, Halden
Prof. Dr. Detlef Krömker
Professur für Graphische Datenverarbeitung
Institut für Informatik
Fachbereich Informatik und Mathematik (12)
Hier wird Wissen Wirklichkeit
Übersicht: Wichtige Datenstrukturen
lineare
Strukturen
nichtlineare
Strukturen
nicht geordnete
Strukturen
geordnete
Strukturen
string
tupel
frozenset
Liste
Stapel
Schlange
list
stack fir
queue
Graph
gerichtet
Menge
Abbildung
set
dictionary
Verbund
···
azyklisch
Feld
array
2
Baum
Vorrangschlange
priority queue
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Die „Brot und Butter“ Datenstruktur
Baum kennen lernen.
Hier wird Wissen Wirklichkeit
Graph
gerichtet
azyklisch
···
Baum
Eine spezielle Klasse „Baum“
realisieren.
tree
Einordnung und Spezialisierung des
Datentyps Baum kennenlernen.
binary tree
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Union
···
Prof. Dr. Detlef Krömker
Unser heutiges Lernziel
3
Record
tree
Prof. Dr. Detlef Krömker
M-Way
quadtree
Suchbaum
Halde
search tree
heap
···
octtree
B-Tree
Hier wird Wissen Wirklichkeit
1
Nicht nur eine „Erfindung“
der Informatik
Stammbaum des Wissens
Band 1 der Encyclopédie ou
Dictionnaire raisonné des sciences,
des arts et des métiers
(28 Bände, vollendet im Jahr 1772)
Jean Baptiste le Rond d'Alembert
und Denis Diderot
Programmieren 1 – Teil 1 – V10
WS 2007/2008
4
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Wo sind wir in Teil1?
V 0
---V 1
V 2
V 3
---V 4
V 5
---V 6
V 7
---V 8
V 9
V10
V11
5
Begrüßung und Einführung
Daten – Information – Wissen
Computer – Algorithmus – Programm
Variablen – Datentypen – Objekte
Elementare numerische Datentypen
Zeichenketten
Verzweigungen und Schleifen
Prozeduren
Aggregierte Datentypen
Klassen
Graphen und Bäume
Bibliotheken
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Übersicht
‣
Graph
Kategorisierung von Graphen
Graphen als Datenstruktur
Adjazenzmatrix
Adjazenzliste
Inzidenzmatrix
Implementierung von Graphen in Python
‣
Baum
Implementierung von Bäumen
‣
Heap
‣
Zusammenfassung
6
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
2
1
5
5
661
2
661
3
1
2
4
3
17
4 17
5
Graph
5
5
7
8
661
7
8
66
20
19
18
9
66
19
18
66
18
20
21 66
18
32
66
648
14
19
66
32
13
13
648
9
648
21
19
14
648
20
15
5
15
21
16
20
21
16
661
17
52
22
50
49
3
51
3
5
22
50
49
17
50
3
52
3
661
18
661
18
5
7
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Graph – Definition (Graphentheorie)
Ein Graph G ist ein geordnetes Paar zweier Mengen: G = (V, E)
Dabei bezeichnet V die Menge der im Graph enthaltenen Knoten (Vertex)
und E die Menge der Kanten (Edge) des Graphen.
Anschaulich ist ein Graph ein Gebilde aus
Knoten (auch Ecken oder Punkte),
die durch Kanten verbunden sein können.
Knoten
1
1
2
Kante
3
Achtung: verschiedene Bilder
können denselben Graphen darstellen.
2
4
3
4
Im Beispiel sind die Knoten mit den Ziffern 1..4 benannt.
8
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Kategorisierung von Graphen
ungerichtete Graphen ohne
Mehrfachkanten:
E ist eine Teilmenge aller
2-elementigen Teilmengen von V
schlicht oder
einfach
e
gerichtete Graphen ohne
Mehrfachkanten:
E ist eine Teilmenge des
kartesischen Produktes V x V
9
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Startknoten von e
Digraph
(Directed Graph).
Endknoten von e
Hier wird Wissen Wirklichkeit
3
Kategorisierung von Graphen (Eigenschaften von E)
ungerichteten Graphen mit
Mehrfachkanten: E ist eine
Multimenge [Elemente können
mehrfach vorkommen] über der
Menge aller 2-elementigen
Teilmengen von V
gerichteten Graphen mit
Mehrfachkanten: E ist eine
Multimenge über dem
kartesischen Produkt V x V
(Multigraph)
(Multigraph)
Hypergraphen eine Teilmenge der
Potenzmenge von V.
10
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Eigenschaften von Graphen
Hat eine Kante e in gerichteten
Graphen die Form (v, v), so
spricht man von einer Schleife.
Ein Graph, bei dem dieses nie
vorkommt, nennt man
schleifenfrei.
Hier gibt es viel mehr zu lernen, siehe
Algorithmen und Datenstrukturen
und …
11
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Graphen als Datenstruktur
Ein Graph als Datentyp sollte mindestens die folgenden Operationen
haben
‣ Einfügen (Kante, Knoten)
‣ Löschen (Kante, Knoten)
‣ Finden eines Objekts (Kante, Knoten).
Die bekanntesten Repräsentation von Graphen im Computer sind
‣ die Adjazenzmatrix (Nachbarschaftsmatrix)
‣ die Adjazenzliste (Nachbarschaftsliste)
‣ die Inzidenzmatrix (Knoten-Kanten-Matrix, seltener genutzt)
12
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
4
Adjazenzmatrix
Ein Graph mit n Knoten kann durch eine n×n-Matrix repräsentiert werden.
Dazu nummeriert man die Knoten von 1 bis n durch und trägt in die Matrix
die Beziehungen der Knoten zueinander ein.
1
1
2
3
1
1
1
2
1
2
1
3
4
4
3
1
4
1
Hypergraphen lassen sich nicht durch eine Adjazenzmatrix darstellen.
Wenn man anstelle der 1 z.B. einen Integerwert zulässt, so können die Kanten
„Gewichte“ haben oder „gefärbt“ sein.
13
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Adjazenzliste
Die Adjazenzliste wird in ihrer einfachsten Form durch eine einfach
verkettete Liste aller Knoten des Graphen dargestellt, wobei
‣ jeder Knoten eine Liste aller seiner Nachbarn (in ungerichteten
Graphen) bzw.
‣ Nachfolger in gerichteten Graphen besitzt.
Vielfachheiten der Kanten Knotengewichte, und Kantengewichte werden
meist in Attributen der einzelnen Elemente gespeichert.
14
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Beispiel Adjazenzliste
1
[1,2,3]
2
[3]
3
[4]
4
[1]
1
2
3
4
Direkte Umsetzung in Python könnte man also verschachtelte Listen implementieren:
(Knoten-) Listen von (Kanten-) Listen: Ist einfach, wenn die Knoten wie oben
nummeriert sind:
Einfügen-Kante Î Kantenliste.append
Einfügen-Knoten: prüfen, ob schon vorhanden, sonst Knotenliste.append
Löschen Kante Î indexiert auf Liste zugreifen und Kantenliste.remove
Löschen Knoten Î Knoten selbst löschen: Knotenliste.remove, dann aber auch
alle Verweise auf diesen Knoten löschen … etwas aufwendiger, geht aber … wie?
Nachteile?
15
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
5
Adjazenzliste (2)
‣
In der Praxis verwendet man meist diese Form der
Repräsentation.
‣
aufwändiger zu implementieren und zu verwalten (zumindest in vielen
Programmiersprachen), bieten aber eine Reihe von Vorteilen
gegenüber Adjazenzmatrizen.
‣ verbrauchen nur linear viel Speicherplatz, was insbesondere bei
dünnen Graphen (also Graphen mit wenig Kanten) von Vorteil
ist, während die Adjazenzmatrix quadratischen Platzbedarf
bezüglich der Anzahl Knoten besitzt (dafür aber kompakter bei
dichten Graphen, also Graphen mit vielen Kanten ist).
‣
16
Zum anderen lassen sich viele graphentheoretische Probleme nur mit
Adjazenzlisten in linearer Zeit lösen.
… das behandeln Sie noch intensiv in Algorithmentheorie
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Ein Beispiel in Python: Initialisierung
Wir wollen nebenstehenden Graph
in Python als Dictionary repräsentieren, aber
allgemeiner, mit nebenstehender Knotenbezeichnung
Vorteile:
• beliebige Bezeichnungen der Knoten möglich
• Datentyp Dictionary sichert Eindeutigkeit der Knoten
A
B
C
D
>>> Adjazenzliste =
{"A":["A","B","C"],"B":["C"],"C":["D"],"D":["A"]}
>>> Adjazenzliste
{'A': ['A', 'B', 'C'], 'C': ['D'], 'B': ['C'], 'D': ['A']}
>>>
17
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Ein paar Operationen auf der Adjazenzliste
>>> Adjazenzliste.update ({"E":["A"]})
>>> Adjazenzliste
{'A': ['A', 'B', 'C'], 'C': ['D'], 'B': ['C'],
'E': ['A'], 'D': ['A']}
>>> k=Adjazenzliste.get ("C")
>>> k
['D']
>>> k.append ("E")
>>> Adjazenzliste.update ({"C":k})
>>> Adjazenzliste
{'A': ['A', 'B', 'C'], 'C': ['D', 'E'], 'B':
['C'], 'E': ['A'], 'D': ['A']}
18
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
A
B
E
C
D
Hier wird Wissen Wirklichkeit
6
Weitere Operationen – hier einmal mit
einer Exception programmiert
>>> Adjazenzliste.pop ("C")
['D', 'E']
>>> Adjazenzliste
{'A': ['A', 'B', 'C'], 'B': ['C'],
'E': ['A'], 'D': ['A']
A
A
B
B
E
E
C
D
D
Problem: Zwei Kanten verweisen ins „Nichts“ … den Knoten C gibt es nicht mehr
Programmieren 1 – Teil 1 – V10
WS 2007/2008
19
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Zwischenruf: Eine interessante
Programmiermethodik - Ausnahmen (Exceptions)
Python unterstützt die Programmierung mit Exceptions.
Exceptions werden während des Programmlaufs generiert (raised)
deuten meist auf Fehler hin und führen zum Abbruch des normalen
Kontrollflusses eines Programmes.
Eine Ausnahme wird mit der raise-Anweisung ausgelöst.
Das allgemeine Format einer raise-Anweisung ist raise Exception [,
value], wobei Exception der Ausnahme-Typ und value ein optionaler
Wert mit spezifischen Details über die Ausnahme ist, z.B.:
raise RuntimeError, 'Fataler Fehler'
20
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Zwischenruf:
Ausnahmen (Exceptions) – Beispiele eingebauter Typen
Exeption
die Superklasse aller Exceptions
ArithmeticError
die Superklasse für OverflowError, ZeroDivisionError
und FloatingPointError
LookupError
die Superklasse von IndexError und KeyError
TypeError
ValueError
Typfehler, z.B. bei falscher Zuweisung
Argumentfehler, die kein TypeError sind
usw.
21
viele mehr
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
7
Das Programmieren mit Exceptions
Um eine Ausnahme abzufangen (catch exeptions), verwendet man die try- und exceptAnweisungen
try:
suite
[except [ExeptionName [, data]]:
suite
…
[else:
suite]
[finally:
suite]
# der zu überwachendeCode
# wird bei Exception ausgeführt
# wird ausgeführt, wenn keine Ex
# wird immer ausgeführt
Tritt eine Ausnahme auf, hört der Interpreter auf, weitere Anweisungen im try-Block auszuführen und
sucht nach einer except-Klausel, die zu der Ausnahme passt. Wenn eine solche Klausel gefunden
wird, wird die Kontrolle an die erste Anweisung dieser except-Klausel abgegeben.
Sonst wird die Ausnahme an den übergeordneten Block weitergegeben, der die try-Anweisung enthält,
in der die Ausnahme aufgetreten ist.
Wenn eine Ausnahme bis auf die höchste Programmebene weitergereicht wird, ohne abgefangen zu
werden, terminiert der Interpreter mit einer Fehlermeldung.
22
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Weitere Operationen – hier einmal mit
einer Exception programmiert
>>> for key in Adjazenzliste:
value = Adjazenzliste.get (key)
try:
value.remove ("C")
Adjazenzliste.update ({key:value})
except ValueError:
continue
A
B
E
D
>>> Adjazenzliste
{'A': ['A', 'B'], 'B': [], 'E': ['A'], 'D': ['A']}
>>>
A
B
E
D
23
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Ein Tipp
Sie sollten jetzt einmal versuchen, eine Klasse Graph in Python zu
implementieren:
Fangen Sie insbesondere alle Fehlersituationen ab:
Knoten der eingefügt werden soll, ist schon vorhanden
Kante, die gelöscht werden soll, ist nicht vorhanden
usw., usw.
Sorry, aber Übung muss sein, und
Programmieren erfordert Disziplin, Ausdauer, abstraktes
Denkvermögen, Kreativität und hohe Lernbereitschaft!
24
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
8
Noch eine Variante zur Implementierung von
Graphen: Inzidenzmatrix (selten genutzt)
‣
Ein Graph mit n Knoten und m Kanten kann auch durch eine
n×m-Matrix repräsentiert werden. Dazu nummeriert man die
2
Knoten von 1 bis n und die Kanten von 1 bis m durch und
3
trägt in die Matrix die Beziehungen der Knoten zu den Kanten ein.
‣
Jede Spalte der Inzidenzmatrix enthält bei
Schleifenfreiheit genau
zwei von Null verschiedene Einträge.
4
In ungerichteten Graphen zweimal die 1 und
in gerichteten Graphen einmal die 1 (Endknoten)
und einmal die -1 (Startknoten).
25
1
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
1
2
3
1
-1 -1 1
2
1
3
4
5
-1
1
1
-1
4
-1
1
Hier wird Wissen Wirklichkeit
Baum
Als Wald bezeichnet man in der Graphentheorie einen ungerichteten
Graphen ohne Kreis (Zyklus). Achtung: Zyklus ≠ Schleife
Ist dieser zusammenhängend, so spricht man von einem
(ungerichteten) Baum.
Ein Wald besteht aus einem oder mehreren Bäumen.
Jeder ungerichtete Baum ist also auch ein Wald.
26
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Gewurzelte Bäume
Neben ungerichteten Bäumen betrachtetet man auch gerichtete Bäume,
die häufig auch als gewurzelte Bäume bezeichnet werden und sich
weiter in In-Trees und Out-Trees unterscheiden lassen.
Es gibt einen ausgezeichneten Knoten, den man Wurzel nennt und für
den die Eigenschaft gilt,
‣ dass alle Kanten von diesem wegzeigen (Out-Tree) oder
‣ zu diesem hinzeigen (In-Tree).
27
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
9
Eigenschaften
die lineare Struktur der Liste wird aufgebrochen.
Der maximale Ausgangsgrad wird als Ordnung eines Out-Trees
bezeichnet (im Beispiel =3)
Alle Knoten mit Ausgangsgrad = 0 bezeichnet man als Blätter.
Alle Knoten, die kein Blatt sind, als innere Knoten. (Manchmal schließt
man die Wurzel dabei aber aus.)
Als Tiefe einen Knotens bezeichnet man die Länge des Pfades von der
Wurzel zu ihm und
als Höhe des Baums die Länge eines längsten Pfades.
28
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Eigenschaften
Für einen von der Wurzel verschiedenen Knoten v
bezeichnet man den Knoten, durch den er mit
einer eingehenden Kante verbunden ist als
Vater, Vaterknoten, Elternknoten oder Vorgänger von v.
Als Vorfahren von v bezeichnet man alle Knoten, die entweder Vater von
v oder Vorgänger des Vaters sind.
Umgekehrt bezeichnet man alle Knoten, die von einem beliebigen Knoten
v aus durch eine ausgehende Kante verbunden sind als Kinder,
Kinderknoten, Sohn oder Nachfolger von v. Als Nachfahren von v
bezeichnet man Kinder von v oder deren Nachfahren.
Als Geschwister oder Geschwisterknoten werden in einem Out-Tree
Knoten bezeichnet, die den gleichen Vater besitzen.
29
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Spezielle Bäume
‣
Bei Binärbäumen ist die Anzahl der Kinder höchstens zwei.
‣
In balancierten Bäumen gilt, dass sich die Höhen des linken und
rechten Teilbaums an jedem Knoten höchstens um eins unterscheiden.
‣
Bei Suchbäumen sind die Elemente in der Baumstruktur geordnet
abgelegt, so dass man schnell Elemente im Baum finden kann.
30
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
10
Partiell geordneter Baum
Ein partiell geordneter Baum T ist ein Baum,
‣
dessen Knoten markiert sind
‣
dessen Markierungen aus einem geordneten Wertebereich stammen
‣
in dem für jeden Teilbaum T' mit der Wurzel x gilt: Alle Knoten aus T'
sind größer markiert als x oder gleich x.
Intuitiv bedeutet dies: Die Wurzel jedes Teilbaumes stellt ein Minimum für
diesen Teilbaum dar. Die Werte des Teilbaumes nehmen in Richtung
der Blätter zu oder bleiben gleich.
31
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Geordnete, strikte und vollständige Binärbäume
‣
Ein Binärbaum heißt geordnet, wenn jeder
innere Knoten ein linkes und eventuell
zusätzlich ein rechtes Kind besitzt
(und nicht etwa nur ein rechtes Kind).
‣
Man bezeichnet ihn als voll oder strikt,
wenn jeder Knoten entweder Blatt ist
(also kein Kind besitzt), oder aber zwei
(also sowohl ein linkes wie ein rechtes)
Kinder besitzt.
‣
Man bezeichnet ihn als vollständig, wenn alle Blätter die gleiche Tiefe besitzen.
Ein vollständiger Binärbaum der Höhe n, n man häufig auch als Bn bezeichnet, hat
genau
2i Knoten in Tiefe i, insbesondere also
‣ 2n+1-1 Knoten,
2n Blätter
‣ 2n-1 innere Knoten,
mit Höhe n die Länge des Pfades zu einem tiefsten Knoten bezeichnet wird.
32
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Eine wichtige Operation auf Bäumen:
Linearisierung oder Traversierung
Es gibt verschiedene Möglichkeiten, die Knoten von Binärbäumen zu
durchlaufen. Diesen Prozess bezeichnet man auch als Linearisierung
oder Traversierung. Man unterscheidet hier in:
‣
‣
33
pre-order (W–L–R): wobei zuerst die
Wurzel (W) betrachtet wird und
anschließend zuerst der linke (L),
dann der rechte (R) Teilbaum
durchlaufen wird,
in-order (L–W–R): wobei zuerst der
linke (L) Teilbaum durchlaufen wird,
dann die Wurzel (W) betrachtet wird
und anschließend der rechte (R)
Teilbaum durchlaufen wird und
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
11
‣
post-order (L–R–W): wobei
zuerst der linke (L), dann der
rechte (R) Teilbaum durchlaufen
wird und anschließend die
Wurzel (W) betrachtet wird.
‣
level-order Beginnend bei der
Wurzel, werden die Ebenen von
links nach rechts durchlaufen.
34
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Rekursive Implementierungen
Funktion Preorder (Baum)
W <- Baum.Wurzel
If Baum.Links <> NULL
L <- Preorder(Baum.Links)
If Baum.Rechts <> NULL
R <- Preorder(Baum.Rechts)
Return W°L°R
Funktion Inorder (Baum)
W <- Baum.Wurzel
If Baum.Links <> NULL
L <- Inorder(Baum.Links)
If Baum.Rechts <> NULL
R <- Inorder(Baum.Rechts)
Return L°W°R
//W:= Wurzel des übergebenen Baumes
//Existiert ein linker Unterbaum?
// dann: L:= Preorder von linkem Unterbaum
//Existiert ein rechter Unterbaum?
// dann: R:= Preorder von rechtem Unterbaum
//Rückgabe: Verkettung aus W, L und R
/W:= Wurzel des übergebenen Baumes
//Existiert ein linker Unterbaum?
// dann: L:= Inorder von linkem Unterbaum
//Existiert ein rechter Unterbaum?
// dann: R:= Inorder von rechtem Unterbaum
//Rückgabe: Verkettung aus L, W und R
Funktion Postorder (Baum)
W <- Baum.Wurzel
//W:= Wurzel des übergebenen Baumes
If Baum.Links <> NULL
//Existiert ein linker Unterbaum?
L <- Postorder(Baum.Links) // dann: L:= Postorder von linkem Unterbaum
If Baum.Rechts <> NULL
//Existiert ein rechter Unterbaum?
R <- Postorder(Baum.Rechts) // dann: R:= Postorder von rechtem Unterbaum
Return L°R°W
//Rückgabe: Verkettung aus L, R und W
35
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Man unterscheidet hier weiter
‣
in binäre Suchbäume mit AVL-Bäumen als balancierte Version und
‣
B-Bäumen sowie diversen Varianten, den B*-Bäumen (die Blattknoten
in einer Liste miteinander verkettet). (Spezielle Suchbäume häufig in
Datenbanksystemen Achtung: B steht nicht für binär!)
‣
In B*-Bäumen wird neben der effizienten Suche einzelner
Datenelemente auch das schnelle sequenzielle Durchlaufen aller
Datenelemente unterstützt).
Eine detaillierte Diskussion würde hier zu weit führen, aber Sie werden in
Ihrem Studium noch viel davon hören, versprochen ;-)
36
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
12
Bäume als Datenstruktur
Gewurzelte Bäume, insbesondere Out-Trees,
Bei beschränkter Ordnung können diese so implementiert werden, dass
jeder Knoten einen festen Satz an Variablen oder ein Array für die
Referenzen auf seine Kinder enthält.
Ein Baum unbeschränkter Ordnung kann implementiert werden, indem
man statt Arrays dynamische Listen verwendet (z. B. in Python).
Häufig besitzen die Knoten auch eine Referenz auf ihren Elternknoten
(back pointer).
37
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Bäume als Datenstruktur (2)
In Programmiersprachen ohne
dynamische Listen hat sich auch
ein Verfahren bewährt, bei dem
ein allgemeiner Baum durch
einen Binärbaum implementiert wird
rote Linie zeigt dabei den realisierten
allgemeinen Baum
Pfeile zeigen die tatsächlich implementierte
Zeigerstrukturen repräsentieren.
Prinzip: linke Zeiger zeigt auf den am weitesten links stehenden Sohn
rechte Zeiger auf den rechten Bruder verweist.
38
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Heap
‣
‣
Der Heap (Haufen, Halde) vereint die Datenstruktur eines Baums mit
den Operationen einer Vorrangwarteschlange.
Je nach Reihenfolge in der Vorrangwarteschlange spricht man von
Min-Heap oder einem Max-Heap.
‣
Häufig hat der Heap neben den minimal nötigen Operationen wie
insert, remove und extractMin (-Max)auch noch weitere Operationen
wie merge oder changeKey.
‣
In einem Heap können Objekte oder Elemente abgelegt und aus
diesem wieder entnommen werden. Sie dienen damit der Speicherung
von Mengen. Den Elementen ist dabei ein Schlüssel zugeordnet, der
die Priorität der Elemente festlegt. Häufig werden auch die Elemente
selbst als Schlüssel verwendet.
39
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
13
Übersicht ... zur Implementierung
Implementierung mit einer
dynamischen Liste in Python
„einfach“ und effizient möglich
Î Übung
Graph
gerichtet
azyklisch
···
Baum
tree
M-Way
binary tree
40
quadtree
Suchbaum
Halde
search tree
heap
···
octtree
Programmieren 1 – Teil 1 – V10
WS 2007/2008
··
B-Tree
Wir betrachten eine Variante zur
Übung ... Programmierung
einer Klasse!
·
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Ein Beispiel für die (unvollständige)
Implementierung eines binären Suchbaums
class Node:
def __init__(self, data=None):
self.data = data
self.left = None
self.right = None
def __str__(self):
return "[%s, %i, %i]" % (str(self.data),
id(self.left), id(self.right))
41
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Implementierung eines binären Suchbaums (2)
class BTree:
def __init__(self):
self.root = None
def _prchilds(self, node):
if node != None:
return "(%s; %s; %s)" (self._prchilds(node.left),
node, self._prchilds(node.right))
else:
return "nil"
42
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
14
Implementierung eines binären Suchbaums (3)
def add(self, data):
if self.root == None:
self.root = Node(data)
else:
curnode = self.root
lastnode = self.root
while curnode != None:
lastnode = curnode
if data < curnode.data:
curnode = curnode.left
direction = -1
# links einfügen
else:
curnode = curnode.right
direction = +1
# rechts einfügen
if direction == -1:
lastnode.left = Node(data)
else:
lastnode.right = Node(data)
43
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Testen unserer Implementierung in der Python Shell
>>> a=BTree()
>>> a.add(4)
>>> a.add(2)
>>> a.add(7)
>>> a
<__main__.BTree instance at 0x00C26828>
>>> a.__str__()
'((nil; [2, 505028048, 505028048]; nil); [4, 13095440,
13095880]; (nil; [7, 505028048, 505028048]; nil))'
44
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Zusammenfassung
‣
Graphen, Bäume, Heaps
‣
ganz wichtige Datenstrukturen
‣
Sie wissen, was das ist und wissen, wie es zu implementieren ist
‣
es fehlen aber noch viele weitergehende Aspekte, ... Datenstrukturen
im 2. Semester, ...
Programmieren erfordert Disziplin, Ausdauer, abstraktes
Denkvermögen, Kreativität und hohe Lernbereitschaft!
45
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
15
Fragen und (hoffentlich) Antworten
46
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
Ausblick
Der Abschluss des Teils 1 am Freitag (für die Klausur immerhin schon 45%):
jeweils nur ausgewählte Elemente:
‣
Module, Pakete
‣
Ein- / Ausgabe
‣
Exceptions und event-based programming
‣
und eine 1. Evaluierung
Danke für Ihre Aufmerksamkeit!
47
Programmieren 1 – Teil 1 – V10
WS 2007/2008
Prof. Dr. Detlef Krömker
Hier wird Wissen Wirklichkeit
16
Herunterladen