Binäre Suche in schwach geordneten Arrays Algorithmen und Datenstrukturen 4. Vorlesung Variante der Aufgabenstellung (häufig in den Anwendungen): Martin Dietzfelbinger A[1] ≤ · · · ≤ A[n] . 25. April 2005 Die Ausgabe zum Input x ist informativer als nur die true/false-Entscheidung, wie bisher betrachtet. Das Array A[1..n] ist schwach aufsteigend“ sortiert, d.h. es ” gilt Sie besteht aus zwei Teilen w und i(x). Der Wahrheitswert w ∈ {true, false} hat dieselbe Bedeutung wie bisher. FG KTuEA, TU Ilmenau AuD – 25.04.2005 FG KTuEA, TU Ilmenau Binäre Suche in schwach geordneten Arrays 1 2 A: 4 4 3 5 6 7 8 9 7 7 7 9 9 10 12 15 15 * Zudem definieren wir: * * i (7) = 3 erstes Vorkommen i (8) = 6 Position des ersten größeren i (20) = 12 Eintrag größer als alle Arrayeinträge i(x) = min({i | 1 ≤ i ≤ n, x ≤ A[i]} ∪ {n + 1}). Wenn x im Array vorkommt, ist dies die Position des ersten (am weitesten links stehenden) Vorkommens von x. Wenn x nicht vorkommt, ist es die Position des ersten Eintrags, der größer als x ist. Wenn kein Eintrag im Array größer als x ist, ist i(x) = n + 1. Allgemein: i(x ) 1 <x FG KTuEA, TU Ilmenau AuD – 25.04.2005 1 Binäre Suche in schwach geordneten Arrays 10 11= n 4 AuD – 25.04.2005 n x * * * 2 FG KTuEA, TU Ilmenau AuD – 25.04.2005 3 Iterative binäre Suche Bei der Algorithmennotation ändern wir ebenfalls den Ansatz: In einer einfachen Schleife (ohne Rekursion) wird die Position i(x) bestimmt. Im Fall der binären Suche ist der Schritt von rekursiver zu iterativer Implementierung leicht, weil es sich um eine tail ” recursion“ handelt: das Resultat des rekursiven Aufrufs wird einfach nach außen durchgereicht“. ” Bei der Suche werden nur ≤-Vergleiche benutzt (keine Gleichheitstests). Algorithmus Binäre Suche (Iterativ) Eingabe: Array A[1..M ], x: Keys; n, 1 ≤ n ≤ M , mit A[1] ≤ · · · ≤ A[n]. (1) a ← 1; b ← n; (2) while a < b do (3) m ← (a+b) div 2 ; (4) if x ≤ A[m] then b ← m else a ← m + 1; (5) if x > A[a] then return (false, a + 1); (6) if x = A[a] then return (true, a) (7) else return (false, a). Anhand von i(x) wird dann in einem Vergleich entschieden, ob x in A[1..n] vorkommt. FG KTuEA, TU Ilmenau AuD – 25.04.2005 4 Satz Der Algorithmus Binäre Suche (Iterativ) auf einem schwach aufsteigend geordneten Array A[1..n] liefert das korrekte Ergebnis. Die Anzahl der Durchläufe durch den Rumpf der Schleife ist höchstens dlog ne. Die Laufzeit ist Θ(log n). AuD – 25.04.2005 AuD – 25.04.2005 5 Erinnerung: Datentyp Dynamische Menge“ ” Mathematisches Modell: Modellierung einer Menge als endliche Menge von Objekten: Sorten: Keys: Sets: nichtleere Menge U {S ⊆ U | S endlich} Boolean: {true, false} Beweis: Übung. FG KTuEA, TU Ilmenau FG KTuEA, TU Ilmenau 6 FG KTuEA, TU Ilmenau AuD – 25.04.2005 7 Erinnerung: Datentyp Dynamische Menge“ ” Mehrere Mengen: Datentyp DynSets Intuitive Aufgabe: Speichere mehrere Mengen S1, . . . , Sr ⊆ U , so dass für jede die Operationen des Datentyps DynSet ausführbar sind und zudem Operationen: empty (()) = ∅ insert(S, x) := S ∪ {x} delete(S, x) := S − {x} ( true, falls x ∈ S member (S, x) := false, falls x ∈ /S FG KTuEA, TU Ilmenau AuD – 25.04.2005 Vereinigung, Durchschnitt, Differenz, Symmetrische Differenz, Leerheitstest Signatur: Wie DynSet, und zusätzlich: union : Sets × Sets → Sets intersection : Sets × Sets → Sets diff : Sets × Sets → Sets symdiff : Sets × Sets → Sets isempty : Sets → Boolean 8 Mathematisches Modell: Wie DynSet, und zusätzlich: FG KTuEA, TU Ilmenau AuD – 25.04.2005 9 union(S1, S2) := S1 ∪ S2 Weitere interessante Kombination: intersection(S1, S2) := S1 ∩ S2 Gleichheitstest: Ist S1 = S2? diff(S1, S2) := S1 − S2 equal(S1, S2) = isempty(symdiff(S1, S2)) symdiff(S1, S2) := (S1 ∪ S2) − (S1 ∩ S2) ( true, falls S = ∅ isempty (S) := false, sonst. Teilmengentest: Ist S1 ⊆ S2? FG KTuEA, TU Ilmenau AuD – 25.04.2005 Operationen erhält man durch subset(S1, S2) = isempty(diff(S1, S2)) Disjunktheitstest: Ist S1 ∩ S2 = ∅? disjoint(S1, S2) = isempty(intersection(S1, S2)) 10 FG KTuEA, TU Ilmenau AuD – 25.04.2005 11 Implementierung des Datentyps DynSets: Repräsentation: Durch Array A[1..N ] of Boolean wird Im Prinzip dieselben Möglichkeiten wie bei DynSet. S = {i | A[i] = 1} Nachtrag: Einfache Implementierungsmöglichkeit für (kleine) Mengen: dargestellt. Bitvektor-Darstellung Platzbedarf: N Bits, d.h. dN/8e Bytes oder dN/32e Speicherworte à 32 Bits Grundmenge U gegeben als Liste (u1, . . . , uN ) Identifiziere ui mit i, d.h. U = {1, . . . , N } Wie immer schreiben wir Beispiel: In Pascal: type Farbe = (rot, gruen, blau, gelb, lila, orange); Palette = set of Farbe; 0 für false und 1 für true. Hier: N = 6. FG KTuEA, TU Ilmenau AuD – 25.04.2005 12 empty : Lege Array A[1..N ] an; for i from 1 to N do A[i] ← 0 ; FG KTuEA, TU Ilmenau AuD – 25.04.2005 13 DynSets-Operationen: Kosten: Θ(N ) union(S1, S2), intersection(S1, S2), diff (S1, S2), symdiff (S1, S2): Jeweils paralleler Durchlauf durch zwei Arrays. insert(S, i): A[i] ← 1 ; Kosten: Θ(N ) Kosten: O(1) isempty (S): Durchlauf durch ein Array. Kosten: Θ(N ) delete(S, i): A[i] ← 0 ; Kosten: O(1) member (S, i): return A[i] ; Kosten: O(1) FG KTuEA, TU Ilmenau AuD – 25.04.2005 14 FG KTuEA, TU Ilmenau AuD – 25.04.2005 15 Zusatz 1: Wenn man zur Bitvektor-Darstellung von S eine int-Variable size hinzufügt, die |S| enthält, dauert der Leerheitstest nur O(1), die anderen Operationen nur um einen konstanten Faktor länger. Selbsttest: Wie ist die Implementierung von empty, insert, delete, union, symdiff zu modifizieren, wenn ein solcher Zähler mitgeführt wird? Zusatz 2: (Nur) Im Fall der Bitvektor-Darstellung lässt sich auch die Komplement-Operation compl : Sets → Sets mit der Semantik (im mathematischen Modell) compl(S) = U − S in Zeit Θ(N ) implementieren. FG KTuEA, TU Ilmenau AuD – 25.04.2005 16 Etwas schlauer: Aufsteigend sortierte Arrays/Listen. Hier: Mit Blindelement“ ( Dummy“, engl.: sentinel“ ” ” ” (Wächter)) Eintrag: ∞, größer als alle Elemente von U . (Siehe GdP 1.) Implementierung des Datentyps DynSets Einfach: Ungeordnete Strukturen (Array/Liste) mit oder ohne Wiederholung. Implementierung von isempty : teste, ob Liste leer bzw. Pegelstand gleich 0. union(S1, S2): Mit Wiederholung: Darstellung von Si hat Länge hi, i = 1, 2. Kosten: Bei Listen O(1) (halte Listenendezeiger!) bei Arrays O(h1 + h2). Für intersection(S1, S2), diff (S1, S2), symdiff (S1, S2): Für jedes Element der Darstellung von S1 durchsuche DarstelKosten: Θ(h1 · h2). lung von S2. FG KTuEA, TU Ilmenau AuD – 25.04.2005 Implementierungen der Operationen union(S1, S2), intersection(S1, S2), diff (S1, S2): 17 diff (S1, S2), sym- Paralleler Durchlauf durch zwei Arrays/Listen, 3 7 analog zum Mischen (Merge) bei Mergesort. oo 25 20 Rechenzeit: Θ(n1 + n2), wo |S1| = n1, |S2| = n2. 4 11 Details: Übung. oo 20 3 4 7 4 7 11 20 11 20 20 25 oo oo oo 3 4 7 11 20 25 oo FG KTuEA, TU Ilmenau AuD – 25.04.2005 18 FG KTuEA, TU Ilmenau AuD – 25.04.2005 19 Kosten für DynSets-Operationen, einfache Implementierung: BV AmW LmW {A,L}oW A-sort L-sort empty insert delete member isempty Θ(N ) O(1) O(1) O(1) O(1) O(1) O(1) O(h) O(h) O(1) O(1) O(1) O(h) O(h) O(1) O(1) O(n) O(n) O(n) O(1) O(1) O(n) O(n) O(log n) O(1) O(1) O(n) O(n) O(n) O(1) union i’section diff symdiff compl Θ(N ) Θ(N ) Θ(N ) Θ(N ) Θ(N ) O(h1 +h2) O(h1h2) O(h1h2) O(h1h2) − O(1) O(h1h2) O(h1h2) O(h1h2) − O(n1n2) O(n1n2) O(n1n2) O(n1n2) − O(n1 +n2) O(n1 +n2) O(n1 +n2) O(n1 +n2) − O(n1 +n2) O(n1 +n2) O(n1 +n2) O(n1 +n2) − Datentyp Deque Double Ended Queue: Schlange mit zwei Enden. Hintergrund: Implementierung einer Liste mit doppelter Verkettung und Anfangs- und Endezeiger Einfügen und Entnehmen an beiden Enden möglich. BV: Bitvektor; A: Array; o: ohne; m: mit; W: Wiederholung; A/L-sort: sortierte(s) Array/Liste N : Länge des Bitvektors; n, n1, n2: Größe von S, S1, S2 h, h1, h2: Länge der Listen-/Arraydarstellung von S, S1, S2 FG KTuEA, TU Ilmenau AuD – 25.04.2005 20 FG KTuEA, TU Ilmenau AuD – 25.04.2005 21 1. Signatur: vorne hinten 1 4 1 5 Sorten: 9 Einfach: head: tail: 1 4 1 5 9 Mit Dummyelementen: head: h FG KTuEA, TU Ilmenau tail: 1 AuD – 25.04.2005 4 1 5 9 Keys Deques Boolean Operationen: empty : → Deques addFirst: Deques × Keys → Deques removeFirst: Deques → Deques first: Deques → Keys addLast: Deques × Keys → Deques removeLast: Deques → Deques last: Deques → Keys isempty : Deques → Boolean t 22 FG KTuEA, TU Ilmenau AuD – 25.04.2005 23 2. Mathematisches Modell: Sorten: Keys: Deques: nichtleere Menge U Seq(U ) = {(a1, . . . , an) | n ∈ N, a1, . . . , an ∈ U } Boolean: {true, false} Operationen: empty (()) = () addFirst((a1, . . . , an), x) := (x, a1, . . . , an) ( (a2, . . . , an), falls n ≥ 1 removeFirst((a1, . . . , an)) := undefiniert, falls n = 0 ( a1, falls n ≥ 1 first((a1, . . . , an)) := undefiniert, falls n = 0 FG KTuEA, TU Ilmenau AuD – 25.04.2005 24 addLast((a1, . . . , an), x) := (a1, . . . , an, x) ( (a1, . . . , an−1), falls n ≥ 1 removeLast((a1, . . . , an)) := undefiniert, falls n = 0 ( an, falls n ≥ 1 last((a1, . . . , an)) := undefiniert, falls n = 0 ( false, falls n ≥ 1 isempty ((a1, . . . , an)) := true, falls n = 0 Implementierung: Siehe GdP1-Vorlesung, doppelt verkettete Liste“. ” FG KTuEA, TU Ilmenau Folgen: Listen mit Zeigern ins Innere Markierte Folge“ ” Idee: Position des Zeigers p als Markierung“ eines Listenele” mentes auffassen. p: first: p zeigt auf Dummy-Element: Markierung undefiniert“. ” Achtung: Dieser Datentyp ist nur als Beispiel zu verstehen. last: 4 1 5 9 Varianten können mehr Operationen (z.B. Anfügen und Löschen am Listenende) oder weniger Operationen umfassen. d Zeiger−Ziele: Einträge oder Dummy am Listenende FG KTuEA, TU Ilmenau AuD – 25.04.2005 25 Datentyp MarkedSequence Java-Terminologie: Iterator 1 AuD – 25.04.2005 1. Signatur: 26 FG KTuEA, TU Ilmenau AuD – 25.04.2005 27 Sorten: Keys, mSeq, Boolean Operationen: empty : → mSeq isempty : mSeq → Boolean addFirst: mSeq × Keys → mSeq removeFirst: mSeq → mSeq first: mSeq → Keys markDefined: mSeq → Boolean markFirst: mSeq → mSeq markNext: mSeq → mSeq markPrev : mSeq → mSeq unmark: mSeq → mSeq readMarked: mSeq → Keys changeMarked: mSeq × Keys → mSeq deleteMarked: mSeq → mSeq insertBeforeMark: mSeq × Keys → mSeq FG KTuEA, TU Ilmenau AuD – 25.04.2005 2. Mathematisches Modell: Sorten: Keys: mSeq: Boolean: {true, false} Der Index p gibt die markierte Position an. Wenn p = n + 1, ist keine Position markiert. Operationen: 28 empty (()) = (1, ()) isempty ((p, (a1, . . . , an))) := ( false, falls n ≥ 1 true, falls n = 0 AuD – 25.04.2005 29 markNext((p, (a1, . . . , an))) := ( (p + 1, (a1, . . . , an)), falls p ≤ n undefiniert, falls p = n + 1 removeFirst((p, (a1, . . . , an))) := ( (p − 1, (a2, . . . , an)), falls n ≥ 1 undefiniert, falls n = 0 ( a1, falls n ≥ 1 first((p, (a1, . . . , an))) := undefiniert, falls n = 0 ( true, falls p ≤ n markDefined((p, (a1, . . . , an))) := false, sonst. AuD – 25.04.2005 FG KTuEA, TU Ilmenau markFirst((p, (a1, . . . , an))) := (1, (a1, . . . , an)) addFirst((p, (a1, . . . , an)), x) := (p + 1, (x, a1, . . . , an)) FG KTuEA, TU Ilmenau (nichtleere) Menge U {(p, (a1, . . . , an)) | n ∈ N, a1, . . . , an ∈ U, 1 ≤ p ≤ n + 1} markPrev ((p, (a1, . . . , an))) := ( (p − 1, (a1, . . . , an)), falls 2 ≤ p ≤ n undefiniert, falls p ∈ {1, n + 1} unmark((p, (a1, . . . , an))) := (n + 1, (a1, . . . , an)) ( ap, falls p ≤ n readMarked((p, (a1, . . . , an))) := undefiniert, falls p = n + 1 30 FG KTuEA, TU Ilmenau AuD – 25.04.2005 31 changeMarked((p, (a1, . . . , an)), x) := ( (p, (a1, . . . , ap−1, x, ap+1, . . . , an)), falls p ≤ n undefiniert, falls p = n + 1 deleteMarked((p, (a1, . . . , an))) := ( (p, (a1, . . . , ap−1, ap+1, . . . , an)), falls p ≤ n undefiniert, falls p = n + 1 (∗ Markierung zum nachfolgenden Eintrag, falls vorhanden ∗) insertBeforeMark((p, (a1, . . . , an)), x) := (p + 1, (a1, . . . , ap−1, x, ap, . . . , an)) (∗ falls unmarkiert: Einfügen an Folgenende, bleibt unmarkiert ∗) FG KTuEA, TU Ilmenau AuD – 25.04.2005 32 Binärbäume Der Datentyp (und die Datenstruktur) Binärbaum tritt überall in der Informatik auf: Implementierung: Mit doppelt verketteten Listen, Listenende, Markierung durch Zeiger realisiert. Details: Selbst überlegen! Viele Erweiterungen möglich. Insbesondere: Konkatenation und Splitten von Folgen. Buch von Güting/Dieker: Folgen mit mehreren Markierungen. Proposition Die Operationen des Datentyps MarkedSequence lassen sich mit doppelt verketteten Listen so implementieren, dass jede Operation Zeit O(1) benötigt. FG KTuEA, TU Ilmenau AuD – 25.04.2005 33 Beispiel 1: Arithmetischer Ausdruck mit zweistelligen Operatoren: ((((x2 · x4) + ((x3 − x7) − (x6/x1))) + (x5 · (x9 · x3)))/((x5 − x6) − x1)) / + • als Repräsentation von binären Ausdrücken (logisch, arithmetisch) - + - • als Codierungs-/Decodierungsbaum x2 • ... x3 34 FG KTuEA, TU Ilmenau x9 / x7 AuD – 25.04.2005 x5 x5 - x4 x1 - • als Entscheidungsbaum AuD – 25.04.2005 am Grundansatz: GdP1-Vorlesung. • als binärer Suchbaum FG KTuEA, TU Ilmenau Dummy/Sentinel x6 x6 x3 x1 35 Beispiel 2: Codierungs-/Decodierungsbaum / + + x4 - x9 / x7 x3 x5 x5 x6 (Wenige Bits für häufige Buchstaben, lange für seltene). x1 - x2 Zeichen aus Alphabet Σ erhalten binäre Codes (auch verschiedener Länge). - Mini-Beispiel: x6 x3 x1 A B C D E F G H I 1100 0110 000 111 10 0011 010 0010 0111 1101 Auswertung: 1) Ordne den Blättern konkrete Werte zu, z.B. x1 = 3, x2 = 4, x3 = −2, x4 = 2, x5 = 7, x6 = 10, x7 = 5, x9 = −5. 2) Werte aus, von den Blättern startend ( bottom-up“). ” Zur Codierung benutzt man direkt die Tabelle. Beispiel: F E I G E hat Codierung 001110011101010. FG KTuEA, TU Ilmenau FG KTuEA, TU Ilmenau AuD – 25.04.2005 36 AuD – 25.04.2005 Präfixfreier“ Code: Kein Codewort ist Anfangsstück eines ” anderen. Damit: eindeutig decodierbar“; ” Fuge zwischen Codes für Buchstaben muss nicht markiert werden. 0 C Kompakte Repräsentation als Binärbaum: 0 0 0 1 0 G C 0 H FG KTuEA, TU Ilmenau 0 E 1 F AuD – 25.04.2005 0 0 B 1 I 0 A 0 E 0 G 1 F 1 0 1 0 B 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). 1 1 1 1 1 0 H 1 1 37 0 0 K 1 D Decodierung: Starte bei Wurzel, laufe Weg im Baum, vom Codewort gesteuert, bis zum Blatt. Wiederhole, bis Wort zuende. Wegen Präfixeigenschaft: im Code keine Zwischenräume nötig. 1 K 38 FG KTuEA, TU Ilmenau AuD – 25.04.2005 39 Beispiel: 0000010100011 liefert ” Binärbaum CHEF “. Wurzel v1 Kante/Zeiger v2 v6 v3 v4 l3 v7 Blatt 40 FG KTuEA, TU Ilmenau l7 l2 l5 AuD – 25.04.2005 v10 l8 v8 l1 rechter Nachfolger von v5 v9 l4 l0 FG KTuEA, TU Ilmenau Vorgänger von v9 v5 l9 l10 l6 AuD – 25.04.2005 41 Flache Auffassung von Binärbäumen Flache Auffassung von Binärbäumen (Forts.) Ein Binärbaum T besteht aus einer endlichen Menge V von inneren“ Knoten, ” einer endlichen Menge L von äußeren“ Knoten ” sowie zwei Funktionen (ii) Für jeden Knoten w ∈ (V ∪ L) − {r} gibt es genau einen Knoten u ∈ V derart dass w = leftchild (u) oder w = rightchild (u). Dieser Knoten wird mit p(w) bezeichnet und heißt der Vorgängerknoten oder Vaterknoten von w. leftchild : V → V ∪ L und rightchild : V → V ∪ L, (iii) Kreisfreiheit“: Für jedes w ∈ V ∪ L gilt: ” Die Folge v0 = w, v1 = p(w), v2 = p(v1), v3 = p(v2), . . . wobei folgendes gilt: (i) In V ∪ L gibt es genau einen Knoten r, der nicht als Wert leftchild (v) oder rightchild (v) vorkommt. Dieser Knoten r heißt die Wurzel. FG KTuEA, TU Ilmenau AuD – 25.04.2005 42 bricht nach endlich vielen Schritten mit einem vd = r ab. Implementierung: Verzeigerte Strukturen, siehe GdP1. FG KTuEA, TU Ilmenau AuD – 25.04.2005 43 ( z ): Rekursive Auffassung von Binärbäumen T = ( T ,x,T ): 1 x z U : Menge von Knotenmarkierungen 2 Z: Menge von Blattmarkierungen Induktive Definition: T 1 T2 (i) Wenn z ∈ Z, so ist (z) ein (U, Z)-Binärbaum. (ii) Wenn T1, T2 (U, Z)-Binärbäume sind und x ∈ U ist, dann ist auch (T1, x, T2) ein (U, Z)-Binärbaum. (iii) Nichts sonst ist (U, Z)-Binärbaum. z-Knoten: Ein Blatt (äußerer Knoten), das zugleich Wurzel ist. Zwei Auffassungen der rekursiv definierten Binärbäume: T1: Linker Unterbaum von T (a) Geschachtelte Tripel. (b) Eine Zeichenreihe. T2: Rechter Unterbaum von T FG KTuEA, TU Ilmenau Knoten mit x: innerer Knoten, Wurzel von T . AuD – 25.04.2005 44 Beispiel: Arithmetischer Ausdruck als Baum U = {+, −, ·, /} und Z = {x1, x2, x3, . . .}. x2 x3 x9 / x7 x5 x5 - x4 x1 - x6 45 Gegeben T = (T1, x, T2), stelle rekursiv eine flache“ Version ” der beiden Unterbäume T1 und T2 her, mit Wurzeln r1 und r2 . - + AuD – 25.04.2005 Umbau von rekursiver zu flacher“ Struktur: ” Gegeben T = (z), so ist die flache“ Version von T ein ” externer Knoten mit Inschrift z. Dieser ist auch die Wurzel. / + FG KTuEA, TU Ilmenau x6 Erzeuge einen neuen inneren Knoten r mit Inschrift x und setze leftchild (r) = r1 und rightchild (r) = r2. x3 x1 ((((x2 · x4) + ((x3 − x7) − (x6/x1))) + (x5 · (x9 · x3)))/((x5 − x6) − x1)) Tupeldarstellung ohne Kommas. FG KTuEA, TU Ilmenau AuD – 25.04.2005 46 FG KTuEA, TU Ilmenau AuD – 25.04.2005 47 Terminologie: • Vater ≡ (unmittelbarer) Vorgänger, engl: parent“, von v: p(v) ” • Binärbaum, engl: binary tree“ ” • linkes Kind ≡ (unmittelbarer) Nachfolger, Sohn, engl: left child“, von v: leftchild (v) ” • (innerer) Knoten v, engl: node“ ” • Knoteneintrag: x = key(v) = key(T ) (v Wurzel von T ) • rechtes Kind ≡ (unmittelbarer) Nachfolger, Sohn, engl: right child“, von v: rightchild (v) ” • Tv : Unterbaum mit Wurzel v • Vorfahr (Vater von Vater von Vater . . . von v), engl: ancestor“ ” • (äußerer) Knoten ≡ Blatt l, engl: leaf “, Pl. leaves“ ” ” • Blatteintrag: z • Nachfahr (Kind von Kind von . . . von v), engl: descendant“ ” • Wurzel, engl: root“ ” FG KTuEA, TU Ilmenau AuD – 25.04.2005 48 FG KTuEA, TU Ilmenau AuD – 25.04.2005 49 Häufiger Spezialfall: • 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 Die externen Knoten haben keinen Eintrag. (Bzw. jeder hat denselben nichtssagenden Eintrag, z.B. −“ .) ” Ein solcher externer Knoten wird auch als leerer Baum“ ” bezeichnet. x5 Achtung: Oft gilt v als (uneigentlicher) Vorfahr/Nachfahr von v. x2 T1 x6 x1 x4 T2 x7 x3 Manchmal bezeichnet man dann sogar die inneren Knoten, die keinen inneren Knoten als Nachfolger haben, als Blätter. FG KTuEA, TU Ilmenau AuD – 25.04.2005 50 FG KTuEA, TU Ilmenau AuD – 25.04.2005 51 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. Beispiele: Höhen von Binärbäumen mit leeren Blättern. Höhe −1 Höhe 0 Auch externen Knoten wird so eine Tiefe zugeordnet. Höhe 3: 0 x5 1 x2 2 T1 d( v )=3 3 x1 AuD – 25.04.2005 T2 x7 x4 x3 4 FG KTuEA, TU Ilmenau x6 52 Definition der Höhe von T : FG KTuEA, TU Ilmenau AuD – 25.04.2005 53 Beispiel: Höhe eines Binärbaums mit nichtleeren Blättern. Die Tiefe oder Höhe h(T ) (auch: d(T )) eines Binärbaums T ist definiert wie folgt: 1. Fall: Die externen Knoten sind leer (): 0 0 (i) h(T ) = −1 für T = 0 C (ii) h(T ) = max{d(v) | v innerer Knoten in T } für T 6= Beobachte: h((T1, x, T2)) = 1 + max{h(T1), h(T2)} 1 1 0 H 1 0 G 1 F 0 E 0 1 0 B 1 1 I 0 A 1 D 1 K Höhe 4, gleich der Länge eines längsten Weges zu einem Blatt. Definition der Höhe von T : 2. Fall: Die externen Knoten sind nicht leer ((z), z ∈ Z): h(T ) := max{d(v) | v äußerer Knoten in T }. FG KTuEA, TU Ilmenau AuD – 25.04.2005 54 FG KTuEA, TU Ilmenau AuD – 25.04.2005 55 Definition der Höhe eines Knotens: Die Höhe h(v) eines Knotens in T ist definiert als die Tiefe h(Tv ) des Teilbaums mit Wurzel v. — Beispiel: Höhe: 5 v1 v6 v3 v4 v9 l3 l1 • Auf Level l liegen höchstens 2l Knoten, l = 0, 1, 2, . . .. Höhe: 0 l7 l2 l5 Höhe: 1 l8 l4 v8 l0 • T hat n + 1 äußere Knoten. Höhe: 2 v10 v7 l9 • Auf Level 0, 1, . . . , l zusammen liegen höchstens 2l+1 − 1 Knoten. l10 l6 • n − 1 ≥ d(T ) ≥ dlog(n + 1)e − 1. Falls Blätter nicht leer! FG KTuEA, TU Ilmenau AuD – 25.04.2005 Es sei T ein Binärbaum mit n ≥ 0 inneren Knoten und leeren äußeren Knoten. Dann gilt: • T hat 2n Zeiger/Kanten. Höhe: 4 v5 v2 Binärbaum-Fakten 1 56 Merke: Die Tiefe eines Binärbaums mit n inneren Knoten ist mindestens log n − 1. FG KTuEA, TU Ilmenau AuD – 25.04.2005 57 Binärbaum-Fakten 2 Es sei T ein Binärbaum mit n ≥ 1 nichtleeren äußeren Knoten. Dann gilt: • T hat n − 1 innere Knoten. • T hat 2n − 2 Zeiger/Kanten. • Auf Level 0, 1, . . . , l zusammen liegen höchstens 2l Blätter, l = 0, 1, 2, . . .. • n ≤ 2d(T ). • n − 1 ≥ d(T ) ≥ dlog ne. FG KTuEA, TU Ilmenau AuD – 25.04.2005 58 FG KTuEA, TU Ilmenau AuD – 25.04.2005 59 Binärbaum-Fakten 3 Merke: Die Tiefe eines Binärbaums mit n nichtleeren äußeren Knoten ist mindestens log n. 0 1 0 1 0 1 0 E 0 C 1 0 1 1 D G 0 1 0 1 0 1 H F B I A K Proposition () Es sei L die Menge der externen Knoten in einem Binärbaum T . X 2−d(l) = 1. Dann gilt: l∈L (Wenn man einige Blätter als nicht existent betrachtet, entsteht die Kraftsche Ungleichung“.) ” FG KTuEA, TU Ilmenau AuD – 25.04.2005 60 Beweis: Wie in einem Kodierungsbaum markiere in jedem inneren Knoten die Kante zum linken Kind mit 0, die zum rechten Kind mit 1. Dem Blatt l entspricht dann eine Bitfolge wl = b1 · · · bd(l). d(T ) bezeichnet die Tiefe des tiefsten Blatts. Jedes wl kann man auf 2d(T )−d(l) Arten zu einer Bitfolge der Länge d(T ) verlängern. Alle so erzeugten Bitfolgen sind verschieden; alle 2d(T ) Bitfolgen werden so erzeugt. X 2d(T )−d(l) = 2d(T ). ⇒ l∈L ⇒ Behauptung. FG KTuEA, TU Ilmenau AuD – 25.04.2005 62 FG KTuEA, TU Ilmenau AuD – 25.04.2005 61