Programmierung und Programmiersprachen Sommersemester 2006

Werbung
Programmierung und Programmiersprachen
Sommersemester 2006
Lehrstuhl für Angewandte Telematik / ee-Business
Institut für Informatik
Universität Leipzig
Stiftungslehrstuhl der Deutschen Telekom AG
[email protected]
www.lpz-ebusiness.de
+49 (341) 97 323 30
PuPS
24.04.2006
Doppelt verkettete Listen
• Bei einfach verketteten Listen ist der Zugriff auf die
Position vor dem Cursor teuer (weil noch mal vom
Anfang aus dahin navigiert werden muss).
• Das Traversieren (Durchlaufen) von vorne nach
hinten und von hinten nach vorne ist daher
asymmetrisch.
• Wenn man beide Durchlaufrichtungen braucht,
dann bietet es sich an, dass die Zellen in beide
Richtungen verweisen.
PuPS
2
1
Doppelt verkettete Listen
• Nachteile:
• mehr Speicherplatz,
• mehr Zeiger-Setzerei beim Löschen und Einfügen
• Vorteil:
• schneller Zugriff in beide Richtungen
PuPS
3
Bäume
• Bäume sind eine fundamentale Datenstruktur, die
man in vielen Bereichen der Informatik braucht.
• Sie können als 2-dimensionale Verallgemeinerung
von Listen aufgefasst werden.
• In Bäumen lassen sich nicht nur die Daten selbst,
sondern auch Beziehungen zwischen Daten
ablegen, z.B. Ordnungs- oder hierarchische
Beziehungen.
• Daher eignen sich Bäume gut zum Wiederfinden
von Daten in existierenden Ordnungen.
PuPS
4
2
Binärbaum zur Repräsentation eines
arithmetischen Ausdrucks
PuPS
5
Implementierung von Binärbäumen
Orientiert an Listen:
• Statt einem Zeiger Next gibt es zwei Zeiger Links und Rechts
• Statt Zelle sagt man Knoten
• Cursor als Zeiger, der bei der Navigation hilft.
class Knoten {
Object Inhalt;
Knoten links;
Knoten rechts;
Knoten (Object e1) {Inhalt = e1;}
}
PuPS
6
3
Implementierung von Binärbäumen
• Ein Baum mit N Knoten hat N-1 Kanten.
• Bei einer Zeiger-Darstellung eines Baums mit N Knoten
gibt es daher 2 * N – (N-1) = N+1 null-Zeiger.
• Ein Binärbaum ist damit ein Knoten mit ein paar
Spezialoperationen:
class BinaerBaum{
private Knoten Wurzel;
private Knoten Cursor;
boolean istLeer () { return Wurzel == null;}
... }
• Anders ausgedrückt: Jeder Knoten ist die Wurzel eines
Binärbaums.
PuPS
7
Bäume – Graphische Darstellung der
Implementation
PuPS
8
4
Auf dem Weg zu HeapSort
Problem: Gegeben sei ein Feld a mit n Werten, die sortiert
werden müssen.
Ausgangssituation: Werte im Feld sind unsortiert
Ziel: sortiertes Feld
Idee 1: kleinsten Wert suchen, diesen mit dem ersten Wert
tauschen, fast immer sehr langsam
Idee 2: benachbarte Werte tauschen, wenn der zweite Wert
größer ist. Solange bis alles sortiert ist. Langsam, wenn von
vorne nach hinten durchgetauscht werden muß.
Idee 3: Verwendung eines Binärbaums (Heapsort)
PuPS
9
Auf dem Weg zu HeapSort
Wir verwenden die Zahlen 1 … n zur Nummerierung der
Knoten eines binären Baums: 1 bildet die Wurzel, und der
Knoten i > 1 hat i/2 als Vater, sodass der linke Sohn
eines Knotens gerade und der rechte Sohn eines Knotens
ungerade ist, sofern der Knoten diese Söhne hat.
Damit können wir ein Feld ebenfalls als Baum darstellen: Ist
das Feld a mit n Komponenten gegeben, so beschriften wir
den Knoten i mit dem Feldelement a[i]. Im folgenden
Beispiel haben wir das Feld mit den
Elementen 7, 12, 0, 5, 9, 1, 3, 8, 13, 10, 15 als
binären Baum dargestellt. Die Knoten i werden mit ihrer
Beschriftung a[i] angegeben.
PuPS
10
5
Auf dem Weg zu HeapSort
Knoten 1
Knoten 2
Knoten 4
8
12
Knoten 3
Knoten 5
5
13
7
9
10
0
1
3
Knoten 6
Knoten 7
15
Knoten 8 Knoten 9 Knoten 10 Knoten 11
PuPS
11
Die Heap-Bedingung
Ein Feld genügt der Heap-Bedingung im Knoten i, falls im
Unterbaum mit Wurzel i jeder Knoten eine kleinere
Beschriftung als seine Söhne trägt.
Die Heap-Bedingung ist in den
Knoten 3, 4, 5, 6, 7, 8, 9, 10, 11 erfüllt, nicht jedoch im
Knoten 2, da
a[2] = 12, a[4] = 5 und a[5] = 9
aber 12 > 5 und 12 > 9,
und auch nicht im Knoten 1, da
a[3] = 0 und a[0] = 7 und 7 > 0.
PuPS
12
6
Lokale Gültigkeit der Heap-Bedingung
Knoten 1
7
Knoten 2 12
Knoten 4
8
Knoten 3
Knoten 5
5
13
9
10
0
1
3
Knoten 6
Knoten 7
15
Knoten 8 Knoten 9 Knoten 10 Knoten 11
Heap-Bedingung im Teilbaum erfüllt
PuPS
13
Auf dem Weg zu HeapSort
Die Heap-Bedingung kann jedoch im Knoten 2 wie folgt
hergestellt werden:
Wir vertauschen die Beschriftung im Knoten 2 mit der
Beschriftung desjenigen Sohnes, der die kleinere
Beschriftung trägt. In diesem Fall handelt es sich um
den Knoten 4.
Wir nehmen hierzu die kleinere der Beschriftungen
der Söhne, damit im Knoten 2 die Heap-Bedingung
lokal erfüllt ist: Die Beschriftung des Knotens 2 ist
kleiner als die Beschriftungen seiner Söhne (Ergebnis
vgl. folgende Folie).
PuPS
14
7
Auf dem Weg zu HeapSort
Knoten 1
Knoten 2
8
5
Knoten 3
Knoten 5
Knoten 4 12
7
13
9
10
0
1
3
Knoten 6
Knoten 7
15
Knoten 8 Knoten 9 Knoten 10 Knoten 11
PuPS
15
Herstellung der lokalen HeapHeap-Bedingung
im Knoten 2
Knoten 1
Knoten 2
8
5
Knoten 3
Knoten 5
Knoten 4 12
13
7
10
9
0
1
3
Knoten 6
Knoten 7
15
Knoten 8 Knoten 9 Knoten 10 Knoten 11
PuPS
16
8
Auf dem Weg zu HeapSort
• Nun ist zwar die Heap-Bedingung im Knoten 2 lokal
hergestellt. Als Folge ist sie aber im Knoten 4 verletzt!
• Die Vertauschung der Beschriftung eines Knotens mit der
kleineren Beschriftung eines seiner Söhne, lässt sich an
dieser Stelle wiederholen, sodass die Beschriftung 12 in ein
Blatt, den Knoten 8, wandert.
• Trivialerweise ist die Heap-Bedingung in einem Blatt erfüllt,
sodass wir durch das beschriebene Vorgehen schrittweise
dafür gesorgt haben, dass die Heap-Bedingung im Knoten 2
hergestellt wurde.
PuPS
17
Auf dem Weg zu HeapSort
Knoten 1
Knoten 2
Knoten 4
12
8
5
Knoten 3
Knoten 5
13
7
10
9
0
1
3
Knoten 6
Knoten 7
15
Knoten 8 Knoten 9 Knoten 10 Knoten 11
PuPS
18
9
Auf dem Weg zu HeapSort
Knoten 1
Knoten 2
Knoten 4
12
8
5
Knoten 3
Knoten 5
13
7
9
10
0
1
3
Knoten 6
Knoten 7
15
Knoten 8 Knoten 9 Knoten 10 Knoten 11
PuPS
19
Auf dem Weg zu HeapSort
• Die Heap-Bedingung gilt aber immer noch nicht für den
Knoten 1, da die Beschriftungen beider Söhne, der Knoten 2
und 3 kleiner sind als die Beschriftung der Wurzel des
Baumes.
PuPS
20
10
Herunterladen