Algorithmen und Datenstrukturen

Werbung
SS17
Algorithmen und Datenstrukturen
3. Kapitel
Binärbäume
Martin Dietzfelbinger
April 2017
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
3.1 Binärbäume: Grundlagen
Der Datentyp (und die Datenstruktur) Binärbaum tritt überall
in der Informatik auf:
• als binärer Suchbaum
• als Repräsentation von binären Ausdrücken
(logisch, arithmetisch)
• als Entscheidungsbaum
• als Codierungs-/Decodierungsbaum
• als binärer Heap (später)
• ...
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
1
Beispiel 1:
Arithmetischer Ausdruck mit zweistelligen Operatoren:
((((x2 · x4) + ((x3 − x7) − (x6/x1))) + (x5 · (x9 · x3)))
/ ((x5 − x6) − x1))
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
2
/
−
+
−
x2
x4
FG KTuEA, TU Ilmenau
x9
/
x7
x5
x5
−
x3
x1
−
+
x6
x6
x3
x1
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
3
Auswertung:
1) Ordne den Blättern konkrete Werte zu, z.B. x1 = 5, x2 = 3,
x3 = −2, x4 = −7, x5 = 7, x6 = 10, x7 = 5, x9 = −5.
2) Werte aus, von den Blättern startend ( bottom-up“).
”
/ −5
40
+
−
−30
+
3
−9
−7 −
−7
FG KTuEA, TU Ilmenau
7
2
5
−
10
−
−2
−3
70
−21
10
/
−5
−8
7
5
10
−2
5
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
4
Beispiel 2: Codierungs-/Decodierungsbaum
Zeichen aus Alphabet Σ erhalten binäre Codes.
Diese können auch verschiedene Länge haben:
Wenige Bits für häufige Buchstaben, viele Bits für seltene.“
”
Mini-Beispiel:
A
1100
B
0110
C
000
D
111
E
10
F
0011
G
010
H
0010
I
0111
K
1101
Zur Codierung von Zeichenreihen benutzt man direkt die
Tabelle.
Beispiel:
FEIGE hat Codierung 0011 10 0111 010 10.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
5
Präfixfreier“ Code: Kein Codewort ist Anfangsstück eines
”
anderen. Damit: eindeutig decodierbar“;
”
Fuge zwischen Codes für Buchstaben muss nicht markiert werden: Schreibe 001110011101010 statt 0011 10 0111 010 10.
Kompakte Repräsentation des Codes als Binärbaum:
0
0
0
C
FG KTuEA, TU Ilmenau
1
1
0
H
1
1
F
0
G
0
E
0
1
0
B
1
1
I
0
A
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
1
D
1
K
6
0
0
0
C
1
1
0
H
1
1
F
0
G
0
E
0
1
0
B
1
1
I
0
A
1
D
1
K
Blätter sind mit Buchstaben markiert; Weg von der Wurzel
zum Blatt gibt das Codewort wieder (links: 0, rechts: 1).
Decodierung: Laufe Weg im Baum, vom Codewort gesteuert,
bis zum Blatt.
Wegen Präfixeigenschaft: im Code keine Zwischenräume nötig.
Beispiel: 0000010100011 liefert CHEF“.
”
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
7
Binärbaum-Terminologie: Überblick
Wurzel
linkes Kind
von v2
v1
Kante/Zeiger
v2
Vater von
v5
v6
v3
v4
v7
v10
l8
l4 v
8
l0
l1
l7
l2
l5
FG KTuEA, TU Ilmenau
rechtes Kind
von v5
v9
l3
v9
l9
l10
Blatt,
externer/äußerer Knoten
l6
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
8
Mathematische Struktur: flach“
”
Definition 3.1.1
Ein Binärbaum T besteht aus einer endlichen Menge V von
inneren“ Knoten, einer dazu disjunkten endlichen Menge L
”
von äußeren“ Knoten sowie einer injektiven Funktion
”
child : V × {left, right} → V ∪ L,
wobei Folgendes gilt:
(i) In V ∪ L gibt es genau einen Knoten r, der nicht als Wert
child(v, left ) oder child(v, right ) vorkommt.
Dieser Knoten r heißt die Wurzel.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
9
Mathematische Struktur: flach“ (Forts.)
”
child(v, left ) [child(v, right )] heißt das linke [rechte] Kind
von v ∈ V .
Weil child injektiv ist, gibt es für jeden Knoten w ∈ (V ∪ L)
mit w 6= r genau einen Knoten u ∈ V mit w = child(u, left)
oder w = child(u, right) (aber nicht beides).
Dieser Knoten u wird mit p(w) bezeichnet und heißt der
Vorgängerknoten oder Vaterknoten von w.
Wir sagen:
Von p(w) nach w
verläuft eine Kante.
w heißt [linkes bzw. rechtes]
Kind von p(w).
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
10
Mathematische Struktur: flach“ (Forts.)
”
Die folgende Struktur erfüllt (i), ist aber kein Binärbaum:
(ii) Kreisfreiheit“: Für jeden Knoten w ∈ V ∪ L gilt:
”
Die Folge v0 = w, v1 = p(w), v2 = p(v1), v3 = p(v2), . . .
bricht nach endlich vielen Schritten mit einem vd = r ab.
(Dadurch ist ein eindeutiger Weg von w zur Wurzel festgelegt. Jeder
Knoten des Binärbaums ist von der Wurzel aus erreichbar.)
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
11
Mathematische Struktur: flach“ (Forts.)
”
Knoten und Kanten können Markierungen (oder Beschriftungen) tragen, die auch als Funktionen dargestellt werden.
Knotenmarkierungen:
(D, Z sind beliebige Mengen.)
Funktionen mV : V → D und mL : L → Z.
Kantenmarkierungen:
(X ist beliebige Menge.)
Funktion mK : V × {left, right} → X .
Beispiel: In einem Codierungsbaum sind die Blätter mit Buchstaben markiert, die beiden Kanten, die aus einem inneren
Knoten herausführen, mit 0 und 1.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
12
Mathematische Struktur: rekursiv
D: Menge von Knotenmarkierungen
Z: Menge von Blattmarkierungen
(Induktive) Definition 3.1.2
(i)
Wenn z ∈ Z, dann ist (z) ein (D, Z)-Binärbaum.
// Blatt mit Markierung z. Auch: z (ohne Klammern), z
(ii)
Wenn T1, T2 (D, Z)-Binärbäume sind und x ∈ D ist,
dann ist auch (T1, x, T2) ein (D, Z)-Binärbaum.
// Wurzel mit Markierung x, linker Unterbaum T1, rechter Unterbaum T2.
(iii)∗ Nichts sonst ist (D, Z)-Binärbaum.
∗
(iii) wird bei induktiven Definitionen meist weggelassen.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
13
Beispiel: D = {a, . . . , z} und Z = N. – Tupeldarstellung:
(((37, b, (17, a, 31)), c, 7), b, ((29, d, (1, r, 23)), z, (13, u, 3)))
Graphische Darstellung:
b
c
7
b
37
d
u
29
a
17
FG KTuEA, TU Ilmenau
z
31
13
r
1
3
23
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
14
Beispiel: Arithmetischer Ausdruck als Baum
D = {+, −, ·, /} und Z = {x1, x2, x3, . . .}.
/
−
+
−
x2
x4
x9
/
x7
x5
x5
−
x3
x1
−
+
x6
x6
x3
x1
((((x2 · x4) + ((x3 − x7) − (x6/x1))) + (x5 · (x9 · x3)))/((x5 − x6) − x1))
Der Ausdruck ist genau die Tupeldarstellung ohne Kommas!
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
15
Mathematische Struktur: rekursiv (Forts.)
(((37, b, (17, a, 31)), c, 7), b, ((29, d, (1, r, 23)), z, (13, u, 3)))
Beachte: Man kann die rekursiv definierten Binärbäume auf
zwei (letztendlich äquivalente) Arten auffassen:
(a) als geschachtelte Tripel
oder
(b) als Zeichenreihen mit Symbolen aus D ∪ Z ∪ {(, ), “,”}.
Auffassung (a) ist mathematisch klarer, da aus gegebenem T = (T1, x, T2)
die Komponenten T1, x und T2 unmittelbar abgelesen werden können
(ohne Syntaxanalyse o. ä.).
Vorteil der rekursiven Auffassung:
Übersichtlichere (rekursive) Programme und Korrektheitsüberlegungen.
Vorteil der flachen“ Auffassung:
”
Eventuell effizientere Ausführung (Schleifen statt rekursive Prozeduraufrufe).
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
16
(((37, b, (17, a, 31)), c, 7), b, ((29, d, (1, r, 23)), z, (13, u, 3)))
(Rekursiver) Umbau von rekursiver zu flacher“ Struktur:
”
Sei T ein (D, Z)-Binärbaum.
Wenn T = z = (z) für ein z ∈ Z, dann ist die flache“
”
Version von T ein äußerer Knoten mit Inschrift z. Dieser ist
auch die Wurzel.
Wenn T = (T1, x, T2), dann werden rekursiv flache“ Versio”
nen der beiden Unterbäume T1 und T2 hergestellt, mit Wurzeln
r1 und r2 und disjunkten Knotenmengen V1, V2, L1, L2.
V := V1 ∪ V2; L := L1 ∪ L2; child := child1 ∪ child2.
Schließlich wird ein neuer innerer Knoten r mit Inschrift x
erzeugt und zusätzlich child(r, left) = r1 und
child(r, right) = r2 gesetzt.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
17
Baum, rekursiv, als Text → flache“ Struktur
”
Umbau von rekursiver Struktur (Text) zu flacher“ Struktur:
”
Prozedur TreeText2Flat()
Verfahren: Liest (D, Z)-Binärbaum (als Textstrom) von links nach rechts,
baut T ( flach“) mit Wurzel v.
”
lies (“;
// lies“ heißt: Zeichen wird verbraucht
”
”
wenn nächstes Zeichen z ∈ Z ist: lies z; T ← z ; dies ist Wurzel von T ;
sonst:
baue leere Wurzel v für T ;
T1 ← TreeText2Flat(); child(v, left) ← Wurzel v1 von T1;
lies ,“;
”
lies Element x ∈ D; data(v) ← x;
lies ,“;
”
T2 ← TreeText2Flat(); child(v, right) ← Wurzel v2 von T2;
lies )“.
”
return T , mit Wurzel v.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
18
Umbau von flacher“ zu rekursiver Struktur:
”
Gegeben: Baum T mit Knotenbeschriftungen
als V , L, child, mV : V → D und mL : L → Z.
Baue rekursiv für jeden Knoten v ∈ V ∪ L einen Baum Tv .
Prozedur Flat2Tree(v) arbeitet folgendermaßen
(die Beschreibung von T ist global gegeben):
Falls v ∈ L ein Blatt mit mL(v) = z ist: return Tv = (z).
Falls v ∈ V ein innerer Knoten mit mV (v) = x ist:
T1 ← Flat2Tree(child(v, left));
T2 ← Flat2Tree(child(v, right));
return Tv = (T1, x, T2).
Um T zu transformieren: Flat2Tree(r) für Wurzel r von T .
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
19
Spezifikation des Datentyps Binärbaum“
”
Datentyp Binärbaum über D: (leere äußere Knoten)
1. Signatur:
Sorten:
Elements
Bintrees
Boolean
Operationen:
empty : → Bintrees
buildTree: Elements × Bintrees × Bintrees → Bintrees
leftSubtree: Bintrees → Bintrees
rightSubtree: Bintrees → Bintrees
data: Bintrees → Elements
isempty : Bintrees → Boolean
2. Mathematisches Modell:
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
20
Sorten:
Elements:
Bintrees:
Boolean:
(nichtleere) Menge D
{T | T ist (D, {−})-Binärbaum}
{true, false}
Op’en:
empty = (−) =: // leerer Baum“
”
buildTree(x, T1, T2) := (T1, x, T2)
T1,
falls T = (T1, x, T2)
leftSubtree(T ) :=
undefiniert, falls T = T2,
falls T = (T1, x, T2)
rightSubtree(T ) :=
undefiniert, falls T = x,
falls T = (T1, x, T2)
data(T ) :=
undefiniert, falls T = false, falls T = (T1, x, T2)
isempty (T ) :=
true, falls T = FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
21
Binärbäume, Implementierung I:
Zeigerstruktur bzw. Referenzstruktur, vgl. AuP-Vorlesung.
Mit markierten externen Knoten.
T:
b
z
c
b
a
37
17
FG KTuEA, TU Ilmenau
d
7
u
r
29
31
1
13
3
23
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
22
Binärbäume, Implementierung II: Leere externe Knoten
T:
b
z
c
d
b
a
u
r
Externe Knoten werden nicht repräsentiert
(null-Zeiger/Referenz).
Oder: 1 externer Knoten `, Referenz auf ` statt null.
Speicherplatzbedarf für n Knoten:
n Dateneinträge, 2n Zeiger/Referenzen, davon n+1 mal null.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
23
Mögliche Erweiterung: Vaterzeiger.
T:
Wurzel
b
z
c
d
b
a
u
r
Erleichtert Navigieren im Baum, besonders bei Verwenden der
flachen“ Auffassung und von iterativen Verfahren.
”
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
24
Implementierung der Operationen des mathematischen
Modells:
Baum wird immer als Zeiger bzw. Referenz auf den Wurzelknoten dargestellt.
empty, isempty, data: klar.
leftSubtree, rightSubtree: Zeiger/Referenz zurückgeben.
buildTree(x, T1, T2) erzeugt einen neuen Knoten (Wurzel) r
mit Eintrag x, die Wurzeln von T1 bzw. T2 werden linkes bzw.
rechtes Kind von r.
Der Benutzer der buildTree-Operation muss sicherstellen,
dass die Knotenmengen von T1 und T2 disjunkt sind!
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
25
3.2 Binärbäume: Terminologie
• Binärbaum, engl: binary tree“
”
• (innerer) Knoten v, engl: node“
”
• Knoteneintrag: x = data(v) = data(T 0) (T 0 = Tv )
x v
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
26
• Tv : Unterbaum mit Wurzel v
x v
Tv
Der Teil von T , der aus den Knoten besteht, deren Weg zur
Wurzel durch v verläuft. Die Wurzel ist v. Dabei kann v ein
beliebiger innerer oder äußerer Knoten sein.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
27
• (äußerer) Knoten ≡ Blatt l, engl: leaf “, Plural leaves“
”
”
• Wurzel, engl: root“
”
z l
• Blatteintrag: z = data(l)
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
28
• Vater ≡ (unmittelbarer) Vorgänger,
engl: parent“, von v: p(v)
”
• linkes Kind ≡ (unmittelbarer) Nachfolger, Sohn,
engl: left child“, von v: child(v, left)
”
• rechtes Kind ≡ (unmittelbarer) Nachfolger, Sohn,
engl: right child“, von v: child(v, right)
”
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
29
• Vorfahr (Vater von Vater von Vater . . . von v),
engl: ancestor“ (Im Bild: v ist Vorfahr von u.)
”
• Nachfahr (Kind von Kind von . . . von v),
engl: descendant“ (Im Bild: u ist Nachfahr von v.)
”
v
u
Achtung: Oft gilt v als (uneigentlicher) Vorfahr/Nachfahr von v.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
30
• Weg in T : Knotenfolge oder Kantenfolge, die von v zu
einem Nachfahren u führt
• Länge eines Wegs (v0, v1, . . . , vs):
Anzahl s der Kanten auf dem Weg
v
Weg der Länge 3
von v nach u
u
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
31
Häufiger Spezialfall:
Die externen Knoten haben keinen Eintrag.
(Bzw. jeder hat denselben nichtssagenden Eintrag, z.B. −“ .)
”
Ein solcher externer Knoten wird auch als leerer Baum“
”
bezeichnet.
"Blätter"
Oft bezeichnet man dann die inneren Knoten, die keinen
inneren Knoten als Nachfolger haben, als Blätter“.
”
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
32
Tiefe/Level eines Knotens
Die Länge (das ist die Kantenzahl) des Wegs
(v0, v1, . . . , vd) von der Wurzel r = v0 zum Knoten v = vd
heißt die Tiefe oder das Level d(v) von Knoten v.
Auch externen Knoten wird so eine Tiefe zugeordnet.
0
1
2
d ( v )=3
v
3
4
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
33
Tiefe/Höhe eines Binärbaums
Die Tiefe oder Höhe d(T ) (auch: h(T )) eines Binärbaums T
ist definiert wie folgt:
1. Fall: Die externen Knoten sind leer ():
d(T ) = max({−1} ∪ {d(v) | v innerer Knoten in T }).
Beobachte induktive Formel:
d(T ) = −1 für T = und
d((T1, x, T2)) = 1 + max{d(T1), d(T2)}.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
34
Beispiele: Tiefen/Höhen von Binärbäumen mit leeren externen
Knoten.
Höhe −1
Höhe 0
Höhe 3:
x5
x2
T1
x6
x1
x4
T2
x7
x3
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
35
Tiefe/Höhe eines Binärbaums
Definition der Tiefe/Höhe von T :
2. Fall: Die externen Knoten sind nicht leer ((z), z ∈ Z):
d(T ) := max{d(v) | v äußerer Knoten in T }.
0
0
0
C
1
1
0
H
1
1
F
0
G
0
E
0
1
0
B
1
1
I
0
A
1
D
1
K
Tiefe 4, gleich der maximalen Länge eines Weges zu einem Blatt.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
36
Definition der Höhe eines Knotens:
Die Höhe h(v) eines Knotens in T ist definiert als die Tiefe
d(Tv ) des Teilbaums mit Wurzel v. – Beispiel:
Höhe: 5
Höhe: 4
Höhe: 2
Höhe: 1
Höhe: 0
Hier angegeben: Fall Blätter nicht leer“.
”
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
37
3.3 Binärbäume: Eigenschaften
Proposition 3.3.1
Es sei T ein Binärbaum mit n ≥ 0 inneren Knoten
und leeren äußeren Knoten. Dann gilt:
(a)
(b)
T hat 2n Zeiger/Kanten. (Beispiel: n = 10, 2n = 20)
T hat n + 1 äußere Knoten. (Beispiel: n + 1 = 11)
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
38
(c) Auf Level l liegen höchstens 2l Knoten, l = 0, 1, 2, . . ..
(d) Auf Level 0, 1, . . . , l zusammen liegen höchstens
1 + 2 + 4 + · · · + 2l = 2l+1 − 1
innere Knoten. Daraus: log(n + 1) ≤ l + 1, für das Level l
mit dem tiefsten inneren Knoten.
(e) n − 1 ≥ d(T ) ≥ dlog(n + 1)e − 1.
Merke: Die Tiefe eines Binärbaums mit n inneren Knoten ist
mindestens log n − 1.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
39
Beweis von 3.3.1:
(a) Jeder innere Knoten hat zwei Zeiger/Kanten zu Kindern.
(b) Jeder Knoten außer der Wurzel hat eine eingehende Kante. Nach (a)
gibt es 2n Kanten, und es gibt n − 1 innere Knoten, die nicht die Wurzel
sind. Daher muss es 2n − (n − 1) = n + 1 äußere Knoten geben.
(c) Beweis durch Induktion über l.
l = 0: Nur die Wurzel hat Level 0, und 20 = 1.
l − 1 → l“: Nach I.V. liegen auf Level l − 1 höchstens 2l−1 Knoten.
”
Jeder davon hat höchstens zwei Kinder. Also liegen auf Level l höchstens
2l−1 · 2 = 2l Knoten.
(d) Sei l das maximale Level, das einen inneren Knoten enthält. Alle Levels
bis l zusammen enthalten n Knoten; nach (c) ist n ≤ 20 + 21 + · · · + 2l.
l+1
Die
Schranke
n
≤
2
− 1 folgt dann mit Hilfe der Summenformel
P
l
k
q
=
(q
− 1)/(q − 1) für geometrische Reihen.
0≤l<k
Dann folgt n + 1 ≤ 2l+1, also durch Logarithmieren: log(n + 1) ≤ l + 1.
(e) In der Situation von (d) gilt l ≥ log(n + 1) − 1; weil l ganzzahlig ist,
folgt l ≥ dlog(n + 1)e − 1.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
40
Proposition 3.3.2
Es sei T ein Binärbaum mit N ≥ 1 nichtleeren äußeren
Knoten. Dann gilt:
(a) T hat n = N − 1 innere Knoten. (Bsp.: N = 11, n = 10)
(b) T hat 2N − 2 Zeiger/Kanten.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
41
(c) N ≤ 2d(T ).
(Beweis: Induktion über Binärbaume, rekursive Struktur.)
(d) N − 1 ≥ d(T ) ≥ dlog N e.
Merke: Die Tiefe eines Binärbaums mit N nichtleeren
äußeren Knoten ist mindestens log N .
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
42
Beweis von 3.3.2:
(a) Dies ist nur eine Umformulierung von Prop. 3.3.1(b).
(b) Dies ist eine Umformulierung von Prop. 3.3.1(a).
(c) Durch (verallgemeinerte) Induktion über d(T ) zeigen wir, dass die
Anzahl NT der Blätter von T nicht größer als 2d(T ) ist.
I.A.: d(T ) = 0: NT = 1 und 20 = 1.
I.Schritt: Sei d(T ) > 0.
Dann hat T eine Wurzel, die innerer Knoten ist, und zwei Unterbäume T1
und T2 mit max{d(T1), d(T2)} = d(T ) − 1.
Baum T hat NT = NT1 + NT2 Blätter.
Nach I.V. gilt NTi ≤ 2d(Ti), also NTi ≤ 2d(T )−1, für i = 1, 2.
Also: NT = NT1 + NT2 ≤ 2 · 2d(T )−1 = 2d(T ).
(d) Ergebnis (c) bedeutet NT ≤ 2d(T ).
Logarithmieren liefert log(NT ) ≤ d(T ).
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
43
Totale innere Weglänge
Wieviele Kanten durchlaufe ich insgesamt, wenn ich zu jedem
inneren Knoten einmal hinlaufe?
0 + 2 · 1 + 3 · 2 + 3 · 3 + 1 · 4 = 21
Totale innere Weglänge ( total internal path length“):
”
P
TIPL(T ) := v∈V d(v). (Im Beispiel: 21.)
Mittlere innere Weglänge:
FG KTuEA, TU Ilmenau
1
n
· TIPL(T ). (Im Beispiel
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
21
10 .)
44
Totale äußere Weglänge
Wieviele Kanten durchlaufe ich insgesamt, wenn ich zu jedem
äußeren Knoten einmal hinlaufe?
2 + 3 · 3 + 5 · 4 + 2 · 5 = 41.
Totale äußere Weglänge ( total external path length“):
”
P
TEPL(T ) := l∈L d(l). (Im Beispiel: 41.)
Mittlere äußere Weglänge: TEPL(T )/(n + 1). (Im Beispiel
41
11 .)
FG KTuEA, TU Ilmenau
45
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
Proposition 3.3.3
Für jeden Binärbaum mit n inneren Knoten gilt:
TEPL(T ) = TIPL(T ) + 2n.
Beweis: Induktion über die Knotenanzahl von Binärbäumen.
( z ):
z
I.A.: n = 0:
TEPL(T ) = 0 (ein Weg der Länge 0) und
TIPL(T ) = 0 (leere Summe, da kein innerer Knoten).
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
46
I.V.: n > 0, Beh. richtig für alle T 0 mit n0 < n inneren
Knoten.
D. h.: TEPL(T 0) − TIPL(T 0) = 2n0.
I.S.:
T = ( T ,x,T ):
1
2
x
T1
T2
n1 = Anzahl innerer Knoten in T1;
n2 = Anzahl innerer Knoten in T2.
Klar: n = 1 + n1 + n2.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
47
Die n1 + 1 bzw. n2 + 1 externen Knoten in den Teilbäumen
hängen in T ein Level tiefer:
TEPL(T ) = (TEPL(T1) + (n1 + 1)) + (TEPL(T2) + (n2 + 1)).
Auch die n1 bzw. n2 internen Knoten in den Teilbäumen
hängen in T ein Level tiefer:
TIPL(T ) =
0 +(TIPL(T1) + n1) + (TIPL(T2) + n2).
|{z}
Wurzel
Subtraktion liefert:
TEPL(T ) − TIPL(T )
=
I.V.
=
(TEPL(T1) − TIPL(T1)) + (TEPL(T2) − TIPL(T2)) + 2
2n1 + 2n2 + 2 = 2n.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
48
Nächstes Ziel: Auch die mittlere Weglänge in Binärbäumen
wächst mindestens logarithmisch mit der Knotenanzahl.
.
1
4
1
+ 3 · 18 + 6 · 16
=1
Lemma 3.3.4
Es sei L die Menge der äußeren Knoten in einem Binärbaum T .
X
Dann gilt:
2−d(l) = 1.
l∈L
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
49
Nächstes Ziel: Auch die mittlere Weglänge in Binärbäumen
wächst mindestens logarithmisch mit der Knotenanzahl.
.
1
4
1/4
1/8
1/8
1/8
1/16
1/16
1
+ 3 · 18 + 6 · 16
=1
1/16
1/16
1/16
1/16
Lemma 3.3.4
Es sei L die Menge der äußeren Knoten in einem Binärbaum T .
X
Dann gilt:
2−d(l) = 1.
l∈L
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
49
Beweis: Wie in einem Kodierungsbaum markiere in jedem
inneren Knoten die Kante zum linken Kind mit 0, die zum
rechten Kind mit 1.
Jedem Blatt l entspricht dann eine Bitfolge wl = b1 · · · bd(l).
Sei D = d(T ) die Tiefe des tiefsten Blatts.
Jedes wl kann man auf 2D−d(l) Arten zu einer Bitfolge der
Länge D verlängern.
Alle so erzeugten Bitfolgen sind verschieden;
alle 2D Bitfolgen werden so erzeugt.
X
⇒
2D−d(l) = 2D .
l∈L
⇒ Behauptung.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
50
Proposition 3.3.5
T hat N = n + 1 äußere Knoten ⇒ TEPL(T ) ≥ N log N .
Beweis: Die Logarithmusfunktion ist konkav :
log((1 − λ)a + λb)) ≥ (1 − λ) log a + λ log b, für 0 ≤ λ ≤ 1.
Daraus:
1
log( M
P
1≤i≤M
ai) ≥
1
M
P
1≤i≤M
log(ai).
Anwenden auf M = N = n + 1 und al = 2−d(l), l ∈ L:
P
P
1
1
−d(l)
log( N l∈L 2
) ≥ N l∈L(−d(l)).
X
P
2−d(l)
D.h.: TEPL(T ) = l∈L d(l) ≥ −N log N1
|l∈L {z
=1
Der letzte Term ist = −N log( N1 ) = N log N .
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
}
51
Folgerung:
Für die mittlere äußere Weglänge eines
Binärbaums T mit N Blättern gilt:
1
TEPL(T ) ≥ log N.
N
Nach Proposition 3.3.3: TEPL(T ) = TIPL(T ) + 2n
Also: TIPL(T ) ≥ TEPL(T ) − 2n ≥ (n + 1) log(n + 1) − 2n > n(log n − 2).
Folgerung:
Für die mittlere innere Weglänge eines
Binärbaums T mit n Knoten gilt:
1
TIPL(T ) > log n − 2.
n
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
52
3.4 Durchläufe durch Binärbäume
(D, Z)-Binärbäume kann man systematisch durchlaufen, die
Knoten nacheinander besuchen und (anwendungsabhängige)
Aktionen an den Knoten ausführen.
Abstrakt gefasst: visit-Operation:
organisiere data-Teil der Knoten als Objekte einer Klasse;
visit(T ) löst Abarbeitung einer Methode von data(T ) aus.
Möglichkeiten für visit bei Knoten v:
– Daten data(v) ausgeben;
– laufende Nummer für v vergeben;
– Zeiger auf v an Liste anhängen;
– zu v gehörende Aktion ausführen
(z. B. arithmetische Operation durchführen) usw.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
53
Inorder-Durchlauf durch T
falls T = (z):
e-visit(z) ;
// besuche äußeren Knoten
falls T = (T1, x, T2):
Inorder-Durchlauf durch T1;
i-visit(x) ;
// besuche inneren Knoten
Inorder-Durchlauf durch T2.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
54
Inorder-Durchlauf durch T
b
1
0
0
1
c
z
1
0
0
1
11
00
00
11
7
1
0
0
1
b
1
0
37
11
00
00
11
a
11
00
00
11
17
31
1
0
11
0 00
1
d
u
1
0
29
11
00
11
00
r
11
00
00
11
1
13
11
00
00
11
3
1
0
0
1
23
11
00
00
00 11
11
00
11
Ausgabe: 37, b, 17, a, 31, c, 7, b, 29, d, 1, r, 23, z, 13, u, 3.
Beobachte: Abwechselnd externe und interne Knoten.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
55
Präorder-Durchlauf durch T
falls T = (z):
e-visit(z) ;
falls T = (T1, x, T2):
i-visit(x) ;
Präorder-Durchlauf durch T1;
Präorder-Durchlauf durch T2;
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
56
Präorder-Durchlauf durch T
1
0
0b
1
1
0
1
0
0z
1
c
11
00
00b
11
37
11
00
00
11
1
0
0
1
1a
0
17
11
00
31
FG KTuEA, TU Ilmenau
00 u
11
d
29
1
0
11
0 00
1
Ausgabe:
1
0
7
1r
0
1
13
11
00
00
11
3
1
0
0
1
23
11
00
00
00 11
11
00
11
b, c, b, 37, a, 17, 31, 7, z, d, 29, r, 1, 23, u, 13, 3
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
57
Postorder-Durchlauf durch T
falls T = (z):
e-visit(z) ;
falls T = (T1, x, T2):
Postorder-Durchlauf durch T1;
Postorder-Durchlauf durch T2;
i-visit(x) ;
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
58
Postorder-Durchlauf durch T
b
c
00
11
b11
00
37
11
00
00
11
17
1
0
FG KTuEA, TU Ilmenau
z
1
0
0
1
1
0
31
1
0
11
0 00
1
Ausgabe:
11
00
7
a
1
0
0
1
d
1
0
0
1
u
11
00
r
29
11
00
1
13
11
00
00
11
1
0
3
1
0
0
1
23
11
00
00
00 11
11
00
11
37, 17, 31, a, b, 7, c, 29, 1, 23, r, d, 13, 3, u, z, b.
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
59
Beispiel: Arithmetischer Ausdruck als Baum
D = {+, −, ·, /} und Z = {x1, x2, x3, . . .}.
/
−
+
−
x2
x4
x9
/
x7
x5
x5
−
x3
x1
−
+
x6
x6
x3
x1
Ordne den Blättern konkrete Werte zu, z.B. x1 = 5, x2 = 3,
x3 = −2, x4 = −7, x5 = 7, x6 = 10, x7 = 5, x9 = −5.
Auswertungsprozedur ordnet jedem Knoten einen Wert zu.
Geeignete Reihenfolge: Postorder-Durchlauf.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
60
Beispiel: Arithmetischer Ausdruck als Baum
D = {+, −, ·, /} und Z = {x1, x2, x3, . . .}.
/
+
−
+
−
3
−2
−5
/
5
7
7
−
−7
5
−
10
10
−2
5
Ordne den Blättern konkrete Werte zu, z.B. x1 = 5, x2 = 3,
x3 = −2, x4 = −7, x5 = 7, x6 = 10, x7 = 5, x9 = −5.
Auswertungsprozedur ordnet jedem Knoten einen Wert zu.
Geeignete Reihenfolge: Postorder-Durchlauf.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
61
Beispiel: Arithmetischer Ausdruck als Baum
D = {+, −, ·, /} und Z = {x1, x2, x3, . . .}.
/
40
+
−30
0
5
+ 1
0
1
−21
11
00
1
00
11
3
−7
−7
−
−2
1
0
8
0
1
−9
11
00
− 4
7
00
11
2
0
1
00
11
/ 3
0
1
00
11
2
0
1
00
11
5
10
−5
0
1
1
0
11
0
1
−81
0
0
10
− 1
0
1
70
11
00
00
11
7
00
11
−3 1
0
0
5
− 1
9
0
1
10
1
0
6
0
1
−5
7
10
−2
5
Ordne den Blättern konkrete Werte zu, z.B. x1 = 5, x2 = 3,
x3 = −2, x4 = −7, x5 = 7, x6 = 10, x7 = 5, x9 = −5.
Auswertungsprozedur ordnet jedem Knoten einen Wert zu.
Geeignete Reihenfolge: Postorder-Durchlauf. (Rote Kreise.)
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
61
Auch möglich: Kombi-Durchlauf:
falls T = (z):
e-visit(z) ;
falls T = (T1, x, T2):
preord-i-visit(x) ;
Kombi-Durchlauf durch T1;
inord-i-visit(x) ;
Kombi-Durchlauf durch T2;
postord-i-visit(x) ;
Ermöglicht Datentransport von der Wurzel nach unten in den
Baum hinein und wieder zurück.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
62
Kombi-Durchlauf durch T
11
00
00b11
11
00
00
11
1
0
37
11
00
00
11
0
1
c 0
1
0
1
0
1
7
1
0
0
1
29
0a 0
1
1
00
11
00
11
00
11
17
31
1
0
11
0 00
1
FG KTuEA, TU Ilmenau
0
1
1
0
0
0b 1
1
0
1
0
1
1
0
11
000
1
z
00
11
00
11
1 0
0
1
0
d 1
1
0
11 u
00
11
00
11
13
0 00
1
r
00
11
00
11
00
00 11
11
1
1
0
3
1
0
0
1
23
11
00
00
00 11
11
00
11
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
63
Beispiel für Anwendung eines Kombi-Durchlaufs:
Generierung einer String-Darstellung eines Binärbaums.
Zeichen werden sequenziell in die Ausgabe geschrieben.
e-visit(z): Schreibe (z)“.
”
preord-i-visit(x): Schreibe (“.
”
inord-i-visit(x): Schreibe , x,“.
”
postord-i-visit(x): Schreibe )“.
”
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
64
Zeitanalyse für Durchlauf
Die Baumdurchläufe können mittels rekursiver Prozeduren
implementiert werden.
Beispiel: Inorder-Durchlauf. Prozedur: inorder(T)
Angewendet auf einen Baum T mit n inneren Knoten.
Für jeden inneren und äußeren Knoten wird die Prozedur inorder(.)
einmal aufgerufen, insgesamt (2n + 1)-mal.
Kosten pro Aufruf:
O(1) plus Kosten für i-visit/e-visit-Operation.
Insgesamt: (2n + 1) · (O(1) + Cvisit), wo Cvisit eine Schranke für die
Kosten der visit-Operationen ist.
Fazit: Baumdurchläufe haben lineare Laufzeit.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
65
Levelorder-Durchlauf
a
0:
c
1:
a
2:
3:
e
d
c
c
d
b
d
f
Wunschausgabe: a cd acc edbdf
zeilenweise von links nach rechts“
”
Benutze Queue Q, die Zeiger/Referenzen auf Binärbaumknoten speichern kann.
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
66
Prozedur Leveldurchlauf (leere äußere Knoten)
Eingabe: v: node; // Wurzel
(1)
Q: Queue für node;
(2)
count ← 0;
(3)
if v <> NIL then // entdecke v
(4)
count++; v.lnum ← count;
(5)
v.level ← 0; enqueue(v);
(6)
while not Q.isempty repeat
(7)
w ← Q.first; Q.dequeue;
(8)
visit(w); // bearbeite w
(9)
p ← w.leftchild;
(10)
if p <> NIL then
(11)
count++; p.lnum ← count; // entdecke p
(12)
p.level ← w.level + 1; enqueue(p);
(13)
p ← w.rightchild;
(14)
if p <> NIL then
(15)
count++; p.lnum ← count; // entdecke p
(16)
p.level ← w.level + 1; enqueue(p);
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
67
Behauptung 3.4.2
Lineare Zeit, Korrektheit“
”
(a) Levelorder-Durchlauf benötigt Zeit
n · tvisit + O(n), wobei tvisit die Zeit für visit angibt.
(b) Der Levelorder-Durchlauf ordnet jedem
Binärbaumknoten v (in v.level) korrekt seine Tiefe zu.
Beweis: Man zeigt durch Induktion über das Level von v:
Jeder innere Knoten v des Binärbaums wird genau einmal
in die Queue eingefügt, genau einmal entnommen und im
Schleifenrumpf (7)-(16) bearbeitet.
Dabei wird die korrekte Levelnummer vergeben.
Weil Queue-Operationen Zeit O(1) benötigen, ist der restliche
Zeitbedarf O(n).
FG KTuEA, TU Ilmenau
Algorithmen und Datenstrukturen – SS17 – Kapitel 3
68
Herunterladen