( i ) = 1/n

Werbung
Durchlaufen eines Binärbaumes
- Baumdurchlauf (tree traversal): Verarbeitung aller
Baumknoten gemäß vorgegebener Strukturierung
- Rekursiv anzuwendende Schritte
1) Verarbeitete Wurzel:
W
2) Durchlaufe linken UB:
L
3) Durchlaufe rechten UB:
R
- Durchlaufprinzip impliziert sequentielle, lineare Ordnung auf der
Menge der Knoten.
6 Möglichkeiten
1
2
3
4
5
6
W
L
L
W
R
R
Konvention:
L
W
R
R
W
L
R
R
W
L
L
W
linker UB vor
rechten UB
G.Heyer
1
Algorithmen und Datenstrukturen
3 Strategien
1)
Vorordnung ( preorder ):
WLR
2)
Zwischenordnung (inorder):
LWR
3)
Nachordnung (postorder):
LRW
Preorder: besuche Wurzel, traversiere linken Teilbaum,
traversiere rechten Teilbaum
Postorder: traversiere linken Teilbaum, traversiere rechten
Teilbaum, besuche Wurzel
Inorder : traversiere linken Teilbaum, besuche Wurzel,
traversiere rechten Teilbaum
Inorder heißt auch symmetrische Ordnung.
G.Heyer
2
Algorithmen und Datenstrukturen
Beispiel:
28
16
12
8
34
19
15
31
49
29
Preorder: 28, 16, 12, 8, 15, 19, 34, 31, 29, 49
Postorder: 8, 15, 12, 19, 16, 29, 31, 49, 34, 28
Inorder: 8, 12, 15, 16, 19, 28, 29, 31, 34, 49
Hinweise: wenn man Baum von der Wurzel aus umfährt, erhält man
Preorder
durch Besuch aller Knoten, an deren linker Seite man
vorbeikommt
Postorder durch Besuch aller Knoten, an deren rechter Seite man
vorbeikommt
Inorder
durch Besuch aller Knoten, an deren unterer Seite man
vorbeikommt
G.Heyer
3
Algorithmen und Datenstrukturen
Rekursive und Iterative Version: LWR
- Rekursive Version : LWR
LWR(Knotenzeiger Wurzel)
{
if (Wurzel != NULL)
{
LWR (Wurzel --> Lsohn);
Verarbeite (Wurzel --> Info);
LWR (Wurzel --> Rsohn);
}
}
G.Heyer
/* End LWR */
4
Algorithmen und Datenstrukturen
- Iterative Version: LWR
Ziel: effizientere Ausführung durch eigene
Stapelverarbeitung
Vorgehensweise:
Nimm, solange wie möglich linke Abzweigung und speichere den
zurückgelegten Weg auf einen Stapel.
Aktion 1: PUSH (S , Current);
Current = Current --> Lsohn ;
Wenn es links nicht mehr weiter geht, wird der oberste Knoten des
Stapels ausgegeben und vom Stapel entfernt. Der Durchlauf wird
mit dem rechten Unterbaum des entfernten Knotens fortgesetzt.
Aktion 2: WriteString (TOP(S) --> Info) ; /*Verarbeite Info */
Current = TOP(S) --> Rsohn;
POP(S);
G.Heyer
5
Algorithmen und Datenstrukturen
Gefädelte Binärbäume
- Weitere Verbesserung von iterativen Durchlaufalgorithmen
- Methode benutzt einen „Faden“, der die Baumknoten in der
Folge der Durchlaufordnung verknüpft.
Zwei Typen von Fäden
• Rechtsfaden verbindet jeden Knoten mit seinem
Nachfolgerknoten in Durchlaufordnung.
• Linksfaden stellt die Verbindung zum
Vorgängerknoten in Durchlaufordnung her.
G.Heyer
6
Algorithmen und Datenstrukturen
Einfügen
• Neue Knoten werden immer als Blätter eingefügt
• Aussehen des Baumes wird durch die Folge der
Einfügungen bestimmt (Reihenfolge der Eingabeelemente!)
Einfügen in binären Suchbäumen
typedef struct Knoten {
struct Knoten
*Lsohn;
Schluesseltyp
Key;
struct Knoten
*Rsohn;
};
typedef struct Knoten *Kptr;
Kptr Wurzel;
G.Heyer
7
Algorithmen und Datenstrukturen
{
void Einfuegen (Knotenzeiger p, int k)
if ( p == NULL )
/* Leerer Baum */
{
p = (struct Knoten *) malloc (sizeof *p);
p --> leftson = NULL;
p --> rightson = NULL;
p --> key = k;
}
else if (k < p --> key)
Einfuegen( p --> leftson, k ) ;
else if (k > p --> key ) Einfuegen ( p --> rightson, k ) ;
else printf („Schluessel bereits vorhanden \n“);
}
G.Heyer
8
Algorithmen und Datenstrukturen
Problem: es können "degenerierte" Bäume entstehen (etwa
Listen).
Entfernen eines Knotens:
Sehr einfach:
Entfernen eines Blattes
Einfach:
Entfernen eines Knotens p mit 1
Nachfolger:
Knoten einfach durch Nachfolger ersetzen
Schwieriger:
Entfernen eines Knotens p mit 2
Nachfolgern: Suche am weitesten links
stehenden Knoten q im rechten Teilbaum
(symmetrischen Nachfolger).
Ersetze p durch q, streiche q aus seiner
ursprünglichen Position.
G.Heyer
9
Algorithmen und Datenstrukturen
Knotenzeiger vatersymnach ( Knotenzeiger p)
/* Liefert Zeiger auf Vater des symmetrischen */
/* Nachfolgers von p -->
*/
{
if ( p --> rightson --> leftson == NULL)
{
p = p --> rightson;
while ( p --> leftson --> leftson == NULL)
p = p --> leftson;
}
vatersymnach = p;
return vatersymnach;
}
G.Heyer
10
Algorithmen und Datenstrukturen
void Entfernen (Knotenzeiger p, int k)
/* Entfernt Knoten mit Schluessel k aus Baum mit Wurzel p */
Knotenzeiger q ;
{
if (p == NULL) printf („Schluessel nicht im Baum \n“);
if (k < p-->key) Entfernen ( p--> leftson, k);
else if ( (k > p --> key) Entfernen (p --> rightson, k );
else if ( p --> leftson == NULL) p = p --> rightson ;
else if (p --> rightson == NULL) p = p --> leftson ;
else
/* zwei Nachfolger */
{ q = vatersymnach (p);
if ( q == p )
{ p --> key = q --> rightson.key ;
q --> rightson = q --> rightson.rightson; }
else { p --> key = q --> leftson.key;
q --> leftson = q --> leftson.rightson ; }
}
}
G.Heyer
11
Algorithmen und Datenstrukturen
Suche in binären Suchbäumen
Direkte Suche:
(Vorgehensweise wie bei Suche nach Einfügeposition
Suchen eines Knotens (rekursive Version)
Suche ( Kptr Wurzel, Schluesseltyp Skey)
{
if (Wurzel == NULL) return NULL;
else if (Wurzel --> Skey < Key) return Suche(Lsohn, Skey);
else if (Wurzel --> Skey > Key) return Suche(Rsohn, Skey);
else return Wurzel;
}
G.Heyer
12
Algorithmen und Datenstrukturen
Suchen eines Knotens (iterative Version)
Finde (Ktpr Wurzel, Schluesseltyp Skey)
{
int Gefunden;
Gefunden = FALSE;
do {
if (Wurzel == NULL) Gefunden = TRUE;
else if(Wurzel --> Skey < Key) Wurzel = Lsohn;
else if (Wurzel --> Skey > Key) Wurzel = Rsohn;
else Gefunden = FALSE;
} while (Gefunden = TRUE);
return Wurzel;
}
Sequentielle Suche
Einsatz eines Durchlauf-Algorithmus (Zwischenordnung)
G.Heyer
13
Algorithmen und Datenstrukturen
Binäre Suchbäume: Zugriffskosten
Kostenmaß: Anzahl der aufgesuchten Knoten bzw. Anzahl
der benötigten Suchschritte oder Schlüsselvergleiche.
• sequentielle Suche
• direkte Suche
Mittlere Zugriffskosten z eines Baumes B erhält man durch
Berechnung seiner gesamten Pfadlänge PL als Summe der
Längen der Pfade von der Wurzel bis zu jedem Knoten Ki.
n
PL ( B )=  Stufe (Ki)
i=1
G.Heyer
14
Algorithmen und Datenstrukturen
Die mittlere Pfadlänge ergibt sich zu l = PL / n .
Maximale Zugriffskosten
Die längsten Suchpfade und damit die maximalen
Zugriffskosten ergeben sich, wenn der binäre Suchbaum zu
einer linearen Liste entartet.
Höhe: h = lmax + 1 = n
G.Heyer
15
Algorithmen und Datenstrukturen
Maximale mittlere Zugriffskosten:
n-1
(n + 1)
( n + 1)
2n
2
zmax = 1/n *  ( i + 1 ) * 1 = n * -------- = -------- = O (n)
i=0
Minimale ( mittlere ) Zugriffskosten
Sie können in einer fast vollständigen oder ausgeglichenen
Baumstruktur erwartet werden.
• Gesamtzahl der Knoten: 2 h-1 -1 < n  2 h -1
• Höhe h = [ log 2 n ] + 1
• Minimale mittlere Zugriffskosten: z min  log 2 n - 1
G.Heyer
16
Algorithmen und Datenstrukturen
Durchschnittliche Zugriffskosten
Extremfälle der mittleren Zugriffskosten sind wenig
aussagekräftig.
Differenz der mittleren zu den minimalen Zugriffskosten ist
ein Maß für die Dringlichkeit von Balancierungen.
Bestimmung der mittleren Zugriffskosten
i
zn
Bl
zi-1
G.Heyer
i-1
Knoten
Br
n-i
Knoten
17
zn - i
Algorithmen und Datenstrukturen
n verschiedene Schlüssel mit den Werten 1, 2, ..., n
seien in zufälliger Reihenfolge gegeben. Die
Wahrscheinlichkeit, dass der erste Schlüssel den Wert i
besitzt, ist 1/n.
(Annahme: gleiche Zugriffswahrscheinlichkeit auf alle
Knoten)
Für den Baum mit i als Wurzel erhalten wir
zn ( i ) = 1/n * ( ( zi-1 + 1 ) * ( i - 1) + 1 + ( zn-1 + 1) * ( n - i ) )
Die Rekursions-Gleichung lässt sich in nicht-rekursiver,
geschlossener Form mit Hilfe der harmonischen Funktion
n
Hn =  1
i =1
G.Heyer
i
darstellen.
18
Algorithmen und Datenstrukturen
Es ergibt sich:
n + 1 ) H - 3 = 2 ln ( n) - c .
zn = 2 * (----------*
n
n
Relative Mehrkosten:
zn
2 ln ( n ) - c
2 ln ( n ) - c
--------- = ---------------  --------------- = 2 ln ( 2 ) = 1.386...
z min log 2 ( n ) - 1
log 2 ( n )
Der ausgeglichene binäre Suchbaum verursacht für alle
Grundoperationen die geringsten Kosten.
Perfekte Balancierung zu jeder Zeit kommt jedoch sehr
teuer.
G.Heyer
19
Algorithmen und Datenstrukturen
Herunterladen