Title: Kapitel 5:
1- Kapitel 5 Von Datenstrukturen zu Abstrakten
Datentypen - 5.1 Zur Erinnerung Datenstrukturen in Pascal
- Listenverarbeitung in Pascal
- 5.2 Abstrakte Datentypen und Objektorientierung
- Brüche als ADT Implementierung -
objektorientiert - Brüche als ADT Implementierung - funktional
- 5.3 Geordnete lineare Zusammenfassungen Listen
bzw. Folgen - Cons-Zelle als Basisklasse
- Statisch-funktionale Listenimplementierung
- Listenimplementierung mit Objektmethoden
- 5.4 Stacks und Queues
- Zustandsorientierte Stack-Implementierung
- 5.5 Priority Queues
- 5.6 Find and Merge
- 5.6.1 Implementierung mit Arrays
- 5.6.2 Implementierung mit Bäumen
2Implementierung von Queues
- Mit doppelt verketteter Liste als Zeigerstruktur
- Doppelt verkettet, da man auf beide Enden der
Liste zugreifen muss. - In einem Array
- Problem Einfügen am Ende und Entfernen am
Anfang führt dazu, dass die Queue durch den
Array wandert. - Lösung Zyklisch in einem Array
3Anwendungen von Queues
- Realisierung von Warteschlangen,
- besonders in Betriebssystemen, z.B.
- Prozesse, Nachrichten, Druckaufträge.
45.5 Priority Queues Mengen mit Insert
und Deletemin
- Priority Queues Warteschlangen, in denen die
Elemente Prioritäten haben. - Es können Elemente mit beliebiger Priorität
eingefügt werden und - es wird immer das (ein) Element mit der höchsten
Priorität entnommen. - Anwendungen/Beispiele
- Patienten im Warteraum einer Krankenhausambulanz
- Betriebssysteme, bes. Multiuser-Betriebssysteme
5- Oft können verschiedene Elemente gleiche
Priorität haben führt zu Multisets (Multimengen) - Multisets Mengen mit Duplikaten (aber ohne
Ordnung der Elemente, also keine Listen/Folgen). -
- Beispiel 1,3,3,7,7,7,10
- auch notiert als (1,1),(3,2),(7,3),(10,1)
- Zu einer Menge S sei M(S) die Menge aller
Multimengen mit Elementen aus S. - In Priority Queues
- Prioritäten natürliche Zahlen
- Höhere Priorität kleinere Zahl
- (dann gibt es automatisch eine höchste
Priorität).
6Datentyp für die Priority Queue, algebraische
Spezifikation
- algebra pqueue
- sorts pqueue, elem
- ops empty ? pqueue
isempty pqueue ? boolean insert
pqueue ? elem ? pqueue deletemin
pqueue ? pqueue ? elem - sets pqueue M(elem)
- functions empty isempty (p)
(p) insert (p,e) p ? e
deletemin (p) (p',e) mit e
min(p) und p'p\e falls p?,
undefiniert sonst - end pqueue.
7Implementierung von Priority Queues
- Z.B. mit partiell geordneten Bäumen.
- Ein partiell geordneter Baum (Heap) ist ein
knotenmarkierter binärer Baum (T, m) (hier ist T
der Baumgraph und m die Markierungsfunktion der
Knoten), in dem für jeden Teilbaum (T ',m) mit
der Wurzel x gilt - für alle y aus T ' ist m(x) ? m(y)
- In der Wurzel steht also jeweils das Minimum
eines Teilbaumes. -
- Analog möglich Ordnung umgekehrt, also in
jeder Wurzel eines Teilbaums das Maximum.
8Definition Heap
- Speziellere Definition eines Heap
- partiell geordneter Binärbaum, der
links-vollständig ist, d.h. die Ebenen werden von
der Wurzel her gefüllt, und jede Ebene von links
nach rechts. - Außerdem Implementierung in einem Array, in
dem die Knoten in dieser Reihenfolge abgelegt
werden.
9Teilheap
Ein Teil T i..k ( 0 ? i ? k ? n ) heißt
Teilheap, wenn gilt für alle j aus
i,...,k ist
m(T j ) ? m(T 2j ) falls 2j ? k
und
m(T j ) ? m(T
2j1) falls 2j1 ? k Ist T i1..n bereits
ein Teilheap, so kann man durch Einsinkenlassen
des Elements T i die Heapeigenschaft
erweitern.
10Aufbau des Heaps
Zum Aufbau des Heaps werden die Elemente
zunächst in die Ebenen unterhalb der Wurzel
eingebracht und zwar maximal 2 j Elemente in
die Ebene j (j 0,..., k-1). Jedes
Einsinkenlassen eines Elementes kostet den
Aufwand O(k-1) O(ld n), also bei n Elementen
O(n ld n). Eine genauere Betrachtung zeigt, dass
der Aufwand pro Element in jeder j-Ebene nur
O(k-j-1) ist. Also erhält man allgemein
1 2 k-2 2 2 k-3 ... (k-1) 2 0 ? 2 k-1
?i gt 0 i / 2i 2 k O(n) Hat man nun das
oberste Element entfernt, so wird das letzte
Element an seine Stelle gebracht und durch
Einsinken- lassen (pro Ebene zwei Vergleiche und
eine Vertauschung) die Heapeigenschaft
wiederhergestellt. Dies kostet einen Aufwand von
O(ld n).
11Entfernen des minimalen Elementes aus einem Heap
und Wiederherstellung der Heapeigenschaft
- Algorithmus deletemin (h)
- lösche das minimale Element aus dem Heap h und
gib es aus - Entnimm der Wurzel ihren Eintrag und gib ihn als
Minimum aus. Nimm den Eintrag der letzten
besetzten Position im Baum, lösche diese Position
und setze ihren Eintrag in die Wurzel ein. - Sei p die Wurzel, und seien q und r die Söhne der
Wurzel - Solange Söhne q oder r existieren und
- (m(p) gt m(q) oder m(p) gt m(r) ) gilt
- vertausche p mit dem Sohn mit dem kleineren
Eintrag. Setze q und r auf die neuen Söhne dieses
Knotens.
12Einfügen in einen Heap
- Algorithmus insert (h, e)
- füge einen neuen Knoten q mit Eintrag e in den
Heap h ein - erzeuge einen neuen Knoten q mit Eintrag e füge
q auf der ersten freien Position in der untersten
Ebene ein falls die unterste Ebene voll besetzt
ist, beginne eine neue Ebene. - Sei p der Vater von e
- Solange p existiert und m(p) gt e gilt
- Vertausche die Einträge in p und q, setze q
auf p und p auf den Vater von p.
13- Sei n die Zahl der Knoten des Heap.
- Aufwand
- für das Entfernen des minimalen Elementes O(log
n). - für das Einfügen eines neuen Knotens O(log n).
- Denn ein Heap hat Höhe log2 (n1) -1
- Aufwand
- für das Aufbauen des Heap durch wiederholtes
Einfügen von Knoten O(n log n). - Wir haben gesehen, dass man einen Heap in O(n)
Schritten aufbauen kann, wenn diese Elemente von
Anfang an alle bekannt sind.
145.6 Partitionen von Mengen mit Find und Merge
- Sei S eine Menge,
- P eine Partition von S, also eine Menge von
Teilmengen von S, die paarweise disjunkt sind und
zusammen die Menge S ergeben. - (Zwei Elemente von S heißen äquivalent, wenn sie
zur gleichen Komponente gehören.) - Wir wollen
- find bei Eingabe eines Elementes die Komponente
finden, zu der es gehört, - merge bei Eingabe (der Namen oder von Elementen)
zweier Komponenten diese verschmelzen.
15Datentyp, algebraisch spezifiziert
- algebra partition
- sorts partition, compname, elem
- ops
- empty ? partition addcomp partition
? compname ? elem ? partition merge
partition ? compname ? compname ? partition
find partition ? elem ? compname - sets
- compnameMenge von Komponentennamen
- (aus einer Menge CN)
partition(ci ,Si) 1 ? i ? n, ci
Komponentenname, - Si Teilmenge von elem,
i?j ? ci ? cj und Si, Sj
elementfremd.
16- functions
- empty bildet auf die leere Partition ab (dann
ist auch die partitionierte Menge S die leere
Menge!) -
- Sei p(c1,S1), ..., (cn,Sn) eine Partition,
- S Vereinigung der Si, und C c1, ...,
cn, C Komp. N. - Sei a aus CN\C, x nicht in S enthalten.
- addcomp(p,a,x) p U (a,x)
- Seien a und b Elemente aus C mit den
zugehörigen Komponenten A und B, d ein Name
aus CN\C oder - da bzw. db.
- merge (p,a,b) (p \ (a,A), (b,B)) U (d,A
U B) - Sei x ein Element aus S.
- find (p,x) a mit (a,A) aus p und x aus A.
- end partition.
175.6.1 Implementierung mit Arrays
- Fall elem 1,..., n und compname 1,...,
n. - Wir benutzen zwei Arrays der Größe n.
- Adjazenzmatrix (components)
- enthält die Komponentennamen und zu jedem
ein Element der Komponente (wenn dies 0, dann
Komponente leer). - Inzidenzmatrix (elems) enthält die
Elementnamen, zu jedem den Namen der zugehörigen
Komponente und ein weiteres Element der
Komponente (wenn dies 0, dann kein noch nicht
erfasstes Element der Komponente). - Man erhält für jede Komponente eine
verkettete Liste!
18p (2,1,2,4,5), (3,3), (6,6). S
1,2,3,4,5,6.
Beispiel
components compname Vertreter (0 unbenutzt) verlinkt mit
1 0
2 1 mit 1
3 3 mit 3
4 0
5 0
6 6 mit 6
elems compname nextelem
1 2 2
2 2 4
3 3 0 (entspricht NIL)
4 2 5
5 2 0
6 6 0
19- Algorithmus find Zeit O(1).
- Algorithmus merge (p, a, b)
- verschmelze die Komponenten von a und b in der
Partition p - Durchlaufe für a die zugehörige Liste in der
Inzidenzmatrix elems und setze für jedes Element
der Liste den zugehörigen Komponentennamen
compname auf b - Sei j der Name des letzten Elements dieser
Liste - Führe dann die folgenden Umbenennungen durch.
- elemsj.nextelem componentsb.firstelem
- componentsb.firstelemcomponentsa.firstel
em - componentsa.firstelem0
- end merge.
20- Aufwand für merge O(n).
- Aufwand für n-1 merge-Anweisungen
- Klar O( Si1n i) O(n²).
- Kann verbessert werden zu O(n log n)
- Schlage immer die kleinere Komponente zur
größeren! - Dann immer eine (mindestens) Verdoppelung der
Größe der Komponente eines Elements. - Amortisierte worst-case Laufzeit von merge O(log
n).
215.6.2 Implementierung mit Bäumen
- Wir benutzen
- ein Array mit den Elementen und
- für jedes Element einen Knoten in einem Baum,
- sowie zu jeder Komponente eine Baumstruktur.
- Name einer Komponente das Element in der Wurzel
des Baums.
22Implementation mit Bäumen
elems
1 -gt 1
2 -gt 2 -gt 1
3 -gt 3 -gt K3 -gt 3
4 -gt 4 -gt 2 -gt 1 -gt K2 -gt 1
5 -gt 5 -gt 2 -gt 1
6 -gt 6 -gt K6 -gt 6
Hier wird jede Komponente durch einen Baum
dargestellt, dessen Knoten die Elemente der
Komponente sind. Dann ist elems ein array1..n
von diesen Bäumen. Die Verweise führen von den
Söhnen zum Vater, die Namen der Komponenten sind
Zeiger auf die Wurzeln der zugehörigen Bäume Der
Wurzelknoten enthält neben dem Namen der
Komponente noch deren Größe.
23Algorithmen
- find(p,x) starte im Array bei x und laufe zur
Wurzel des Baums der Komponente. - Aufwand O( Höhe des Baums).
- merge(p,a,b) Mache a zum Sohn von b oder
umgekehrt. - Aufwand O(1).
- Höhenbeschränkung zu erreichen durch Wurzel der
kleineren Komponente wird Sohn der Wurzel der
größeren Komponente. - Dann Höhe ? log n.
24Pfadkompression
- Noch eine Verbesserung Pfadkompression
- bei find(p,x) mache alle Knoten auf dem Pfad
von x zur Wurzel zu Söhnen der Wurzel. - Dann n find-Operationen beinahe in linearer Zeit
O(n G(n)) - Dabei wächst G sehr langsam
- G(n) ? 5 für n ? 265536.
25- Kapitel 6 Suchbäume und weitere
Sortierverfahren - 6.1 Binäre Bäume
- Die Klasse BinTree mit Traversierungsmethoden
- 6.2 Suchbäume
- 6.2.1 AVL Bäume
- 6.3 HeapSort und BucketSort
- 6.3.1 HeapSort
- 6.3.2 BucketSort
266.1 Binäre Bäume
- Bäume als Graphen
- Gerichtete Graphen bestehen aus Knoten
(Knotenmenge V) und Kanten (Kantenmenge
ETeilmenge von V ?V). - Bäume spezielle gerichtete Graphen
- (1) haben einen ausgezeichneten Knoten, die
Wurzel w, - (2) haben die Eigenschaft, dass zu jedem
Knoten k des Baumes genau eine Kantenfolge (ein
Pfad) existiert, die w mit k verbindet. - (3) haben keine Zykeln, d.h. es gibt keine
Kantenfolge, die den gleichen Knoten mit sich
verbindet. - Bäume andere Charakterisierung zusammenhängende
gerichtete Graphen mit (V) (E) 1.
27Graphische Darstellung
- Bäume werden graphisch i.d.R. so dargestellt,
dass die Wurzel die oberste Position einnimmt und
Kanten von oben nach unten gerichtet sind
(Hierarchie). - Knoten, von denen keine weiteren Kanten ausgehen,
heißen äußere Knoten oder Blätter. - Die anderen Knoten heißen innere Knoten.
28Beispiel Binärbaum zum Ausdruck ((12/4)2)
- Hier
- innere Knoten Kreise
- Blätter Rechtecke
29Bezeichnungen
- Ist (k,k) eine Kante in einem Baum, so heißt
- k Kind (Sohn, Nachfolger) von k und
- k Vorgänger von k.
- Nachfolgerrelation eines Baumes
- (k, k) k innerer Knoten, k Nachfolger
von k - Vorgängerfunktion eines Baumes partielle
Funktion, die jedem Knoten außer der Wurzel den
Vorgänger zuordnet.
30- Binärbäume Bäume, in denen jeder Knoten maximal
zwei Nachfolger hat. - Direkte Definition von Binärbäumen
- T ist genau dann ein Binärbaum (mit
Knotenelementen aus M), wenn - (i) T lt T1, x, T2 gt wobei T1, T2 Binärbäume
und x aus M oder - (ii) T lt gt (leere Struktur, null)
31- Hier
- Bei einem Binärbaum T lt T1, x, T2 gt ist x die
Wurzel des Baums. - Knoten die Wurzeln von Teilbäumen.
- Kanten von der Wurzel x eines Teilbaumes
- T lt T1, x, T2 gt zu den Wurzeln von T1 und
T2. - Wir identifizieren im Folgenden häufig einen
Knoten mit dem entsprechenden Wert (Inhalt) x. - Ein Knoteninhalt kann in einem Binärbaum mehrfach
vorkommen. - Eindeutige Identifizierung eines Knoten durch
Links-/Rechts-Entscheidungen von der Wurzel zu
dem Knoten Bitfolge. - Diese Definition kann auf k-näre Bäume erweitert
werden.
32Pfade
- Pfad Knotenfolge x0 , x1 , ... , xn , wobei
jeweils xi1 Nachfolger (Kind) von xi ist, d.h.
(xi,xi1) Kante. - Länge eines Pfades Zahl der Kanten, hier also
n. - Ein nur aus einem Knoten bestehender Pfad hat
die Länge 0.
33- Die Höhe eines Baumes T ist die maximale Länge
eines Pfades in T. - (Die Anzahl der Ebenen im Baum ist um eins
größer als die Höhe des Baumes.) - Ein Binärbaum heißt vollständig, wenn alle Ebenen
bis auf die letzte vollständig besetzt sind. - links-vollständig, wenn er vollständig ist und
die unterste Ebene von links nach rechts
aufgefüllt ist. - Auch diese Definitionen gelten für k-näre Bäume