@@ -730,8 +730,8 @@ \section{Bäume für's Suchen}
730730%
731731\begin {aufgabeinline }
732732 Schreibe mit Hilfe von \lstinline {member?} eine Funktion, die von
733- zwei Listen alle Elemente liefert, die in beiden Listen stehen, also
734- deren Schnittmenge. Wie lange braucht diese Funktion im
733+ zwei Listen alle Elemente liefert, die in beiden Listen stehen.
734+ Wie lange braucht diese Funktion im
735735 ungünstigsten Fall?
736736\end {aufgabeinline }
737737%
@@ -805,7 +805,7 @@ \section{Bäume für's Suchen}
805805natürlich auch eine Signatur
806806\lstinline {true}\indexvariable {true} für \lstinline {#t}.
807807
808- Als Beispielbaum für die Tests benutzen wir diesen hier :
808+ Hier ein Beispielbaum und einige Tests, die ihn benutzen :
809809%
810810\ begin{lstlisting}
811811(define tree4
@@ -814,11 +814,6 @@ \section{Bäume für's Suchen}
814814 (make-node 17
815815 (make-node 10 #f (make-node 12 #f #f))
816816 #f)))
817- \end {lstlisting }
818- %
819- Hier sind ein paar Tests:
820- %
821- \ begin{lstlisting}
822817(check-expect (tree-member? 5 tree4) #t)
823818(check-expect (tree-member? 17 tree4) #t)
824819(check-expect (tree-member? 3 tree4) #t)
@@ -890,20 +885,16 @@ \section{Bäume für's Suchen}
890885 (else #f))))
891886\end {lstlisting }
892887%
893- Fertig!
894888
895889\section {Sortierte Bäume herstellen }
896890
897891In den Testfällen für \lstinline {tree-member?} haben wir immer den
898892Baum \lstinline {tree4} vwerwendet, den wir direkt mit
899893\lstinline {make-node} konstruiert haben. Dabei mussten wir selbst
900894darauf achten, dass er auch sortiert ist. In diesem Abschnitt
901- automatisieren wir diese Konstruktion, dann kann dabei auch kein
902- Fehler passieren. (Wenn wir korrekt programmieren zumindest.)
903-
895+ automatisieren wir diese Konstruktion.
904896Wir schreiben dafür eine Funktion, die ein neues Element in einen
905- bestehenden sortierten Baum einfügt. Kurzbeschreibung und Signatur
906- sind wie folgt:
897+ bestehenden sortierten Baum einfügt:
907898%
908899\ begin{lstlisting}
909900; Zahl in sortierten Baum einfügen
@@ -938,8 +929,8 @@ \section{Sortierte Bäume herstellen}
938929Seite~\pageref {cha:properties } werden wir zeigen, wie man Funktionen
939930wie \lstinline {tree-insert} besser testet.
940931
941- Aber jetzt geht's erst einmal mit der Funktion selbst los. Gerüst und
942- Schablone sind genau wie bei \lstinline {tree-member?}:
932+ Gerüst und
933+ Schablone von \lstinline { tree-insert} sind genau wie bei \lstinline {tree-member?}:
943934%
944935\ begin{lstlisting}
945936(define tree-insert
@@ -998,7 +989,7 @@ \section{Sortierte Bäume herstellen}
998989%
999990Es bleiben noch zwei Fälle, in denen der einzufügende Wert links
1000991beziehungsweise rechts von der Knotenmarkierung liegt. Er muss
1001- entsprechend im linken oder rechten Teilbaum eingefügt werden: Genau
992+ entsprechend im linken oder rechten Teilbaum eingefügt werden. Genau
1002993das erledigen die beiden rekursiven Aufrufe aus der Schablone. Der
1003994jeweils andere Teilbaum bleibt so wie er ist:
1004995%
@@ -1057,7 +1048,6 @@ \section{Suchbäume}
10571048\lstinline {<} hinschreiben. Das nervt und ist jedesmal eine
10581049Gelegenheit für einen Fehler, weil wir das vollkommen konsistent
10591050machen müssen.
1060-
10611051Wir wollen also versuchen, ohne diese zusätzlichen Parameter
10621052auszukommen. Dazu benutzen wir einen Trick und packen die Funktionen
10631053für \lstinline {=} und \lstinline {<} zusammen mit \lstinline {tree}.
@@ -1131,9 +1121,8 @@ \section{Suchbäume}
11311121 ...))
11321122\end {lstlisting }
11331123%
1134- Für den Rumpf können wir die Funktion
1135- \lstinline {tree-member?} wiederverwenden. Dazu kopieren wir sie
1136- in die Definition von \lstinline {search-tree-member?}:
1124+ Wir verwenden \lstinline {tree-member?} wieder und kopieren sie dafür
1125+ in den Rumpf:
11371126%
11381127\ begin{lstlisting}
11391128(define search-tree-member?
@@ -1142,6 +1131,7 @@ \section{Suchbäume}
11421131 (search-tree-label-=?-function search-tree)
11431132 (search-tree-label-<?-function search-tree)
11441133 (search-tree-tree search-tree)
1134+ ...
11451135 (define tree-member?
11461136 (lambda (value tree)
11471137 (cond
@@ -1168,6 +1158,7 @@ \section{Suchbäume}
11681158 (search-tree-label-=?-function search-tree)
11691159 (search-tree-label-<?-function search-tree)
11701160 (search-tree-tree search-tree)
1161+ ...
11711162 (define tree-member?
11721163 (lambda (value tree)
11731164 (cond
@@ -1234,20 +1225,22 @@ \section{Suchbäume}
12341225
12351226\section {Sortierte Bäume sind effizienter als Listen }
12361227
1237- Intuitiv ist die Idee mit dem sortierten Baum beim Suchen
1238- effizienter. Aber hält diese Intuition auch einer mathematischen
1239- Untersuchung stand? Betrachte dazu den Baum in "< Ebenen"> --
1240- erste Ebene ist die Wurzel, die zweite Ebene deren Teilbäume, die
1241- dritte Ebene wiederum deren Teilbäume undsoweiter. Dann passen in
1242- jede Ebene doppelt soviele Knoten wie in die Ebene darüber.
1243-
1244- In einen Baum der Tiefe 1 passt auch nur $ 1 = 2 ^0 $ Knoten, in einen
1228+ Sortierte Bäume sind beim Suchen effizienter. Um zu verstehen warum,
1229+ betrachte den Baum in "< Ebenen"> ~-- die erste Ebene ist die Wurzel,
1230+ die zweite Ebene deren Teilbäume, die dritte Ebene wiederum deren
1231+ Teilbäume undsoweiter. Je besser der Baum sortiert ist, desto weniger
1232+ Ebenen gibt es, und desto weniger Schritte sind beim Suchen notwendig.
1233+
1234+ Ein
1235+ jede Ebene passen doppelt soviele Knoten wie in die Ebene darüber.
1236+ In einen Baum der Tiefe 1 passt $ 1 = 2 ^0 $ Knoten, in einen
12451237der Tiefe 2 passen $ 2 ^0 + 2 ^1 = 1 +2 = 3 $ Knoten, dann 7, dann 15
1246- undsoweiter. Dir fällt vielleicht auf, dass die Zahlen $ 1 $ , $ 3 $ , $ 7 $ , $ 15 $
1247- allesamt Vorgänger einer Zweierpotenz sind. Wir können deshalb
1238+ undsoweiter.
1239+ Dir fällt vielleicht auf, dass die Zahlen $ 1 $ , $ 3 $ , $ 7 $ , $ 15 $
1240+ jeweils Vorgänger einer Zweierpotenz sind. Wir können deshalb
12481241versuchen, das zu einer Formel zu verallgemeinern. Die Tiefe des
12491242Baums heißt dabei $ t$ . Dann nehmen wir an (oder hoffen zumindest),
1250- dass für für alle
1243+ dass für für alle $ t $ gilt:
12511244%
12521245\begin {displaymath }
12531246 2^0 + ... + 2^{t-1} = \sum _{i=0}^{i=t-1} 2^i = 2^t-1
@@ -1257,19 +1250,14 @@ \section{Sortierte Bäume sind effizienter als Listen}
12571250vollständige Induktion anwenden nach der Anleitung in
12581251Abschnitt~\ref {sec:nat-induction-ka } auf
12591252Seite~\pageref {sec:nat-induction-ka }.
1260- Wir müssen also beweisen, dass für alle $ t\in \mathbb {N}$ gilt:
1253+ Wir müssen beweisen, dass für alle $ t\in \mathbb {N}$ gilt:
12611254%
12621255\begin {displaymath }
12631256 \sum _{i=0}^{i=t-1} 2^i = 2^t-1
12641257\end {displaymath }
12651258%
1266- $ t=0 $ :
1267- %
1268- \begin {displaymath }
1269- \sum _{i=0}^{i=0-1} 2^i = 2^0 - 1
1270- \end {displaymath }
1271- %
1272- Beweis:
1259+ Für $ t=0 $ läuft die Summe von $ 0 $ bis $ -1 $ . und ist deshalb
1260+ leer. Das Ergebnis ist das neutrale Element bezüglich der Addition:
12731261%
12741262\begin {eqnarray* }
12751263 \sum _{i=0}^{i=-1} 2^i
@@ -1278,12 +1266,6 @@ \section{Sortierte Bäume sind effizienter als Listen}
12781266 &=& 2^0 - 1
12791267\end {eqnarray* }
12801268%
1281- (Vielleicht kommt Dir komisch vor, dass die Summe von $ 0 $ bis $ -1 $
1282- läuft. Da es keine Zahl zwischen $ 0 $ bis $ -1 $ gibt, ist die Summe
1283- leer und deshalb das neutrale Element bezüglich der Addition.)
1284-
1285- \smallskip
1286-
12871269\noindent Induktionsvoraussetzung:
12881270\begin {displaymath }
12891271 \sum _{i=0}^{i=t-1} 2^i = 2^t-1
@@ -1398,7 +1380,7 @@ \section{Suchbäume balancieren}
13981380%
13991381In diesem Abschnitt wollen wir eine Variante von
14001382\lstinline {search-tree-insert} schreiben, bei der niemals so ein
1401- entarteter Suchbaum herauskommen kann und die stattdessen den Baum
1383+ entarteter Suchbaum herauskommen kann und die den Baum
14021384immmer \index {balancieren!von Suchbäumen}\textit {balanciert }.
14031385
14041386Spätestens jetzt betreten wir einen Bereich der Programmierung, der in
@@ -1510,8 +1492,7 @@ \subsection{Größenannotierte Bäume}
15101492diese zum Vergleich:
15111493%
15121494\ begin{lstlisting}
1513- (: make-node (%label (tree-of %leaf %label)
1514- (tree-of %leaf %label)
1495+ (: make-node (%label (tree-of %leaf %label) (tree-of %leaf %label)
15151496 -> (node-of %leaf %label)))
15161497\end {lstlisting }
15171498%
@@ -1704,7 +1685,7 @@ \subsection{Balancierte Suchbäume}
17041685 (lambda (element)
17051686 (search-tree-of (sized-label-of element))))
17061687\end {lstlisting }
1707- \vspace *{-2ex }
1688+ \vspace *{-4ex }
17081689\end {aufgabeinline }
17091690%
17101691Wir machen aus
@@ -1993,6 +1974,8 @@ \section{Ausbalancieren durch Rotation}
19931974Rotation ist etwas komplizierter, darum heißt sie "< doppelte">
19941975Rotation, die erste heißt entsprechend "< einfach"> .
19951976
1977+ \pagebreak [4]
1978+
19961979\begin {aufgabeinline }
19971980 Warum bewirken die Rotationen in
19981981 Abbildung~\ref {fig:search-tree-rotation } nicht, dass die Bäume auf
@@ -2005,7 +1988,6 @@ \section{Ausbalancieren durch Rotation}
20051988größer als der andere. Nehmen wir mal an, das ist $ X$ . Dann
20061989vermindert eine einfache Rotation das Ungleichgewicht zwischen links
20071990und rechts.
2008-
20091991Wenn aber $ Y$ größer ist $ Z$ , dann macht die einfache Rotation das
20101992Ungleichgewicht \emph {größer }: Der eh größere Brocken $ Y$ tut sich
20111993dann auch noch mit $ X$ zusammen, während der kleine Brocken $ Z$ rechts
@@ -2100,7 +2082,7 @@ \section{Ausbalancieren durch Rotation}
21002082gegenüber dem gerade behandelten Fall "< gespiegelt"> . Auch der letzte
21012083Fall fehlt noch: Der tritt dann ein, wenn der Baum kein exzessives
21022084Ungleichgewicht aufweist. Dann könnten wir einfach
2103- \lstinline {make-sized-node} benutzten .
2085+ \lstinline {make-sized-node} benutzen .
21042086
21052087Hier die ganze Funktion:\label {func:make-balanced-node }
21062088%
@@ -2122,8 +2104,7 @@ \section{Ausbalancieren durch Rotation}
21222104 (cond
21232105 ((< (sized-tree-size Y) (sized-tree-size Z))
21242106 (make-sized-node c
2125- (make-sized-node a X Y)
2126- Z))
2107+ (make-sized-node a X Y) Z))
21272108 (else
21282109 (define b (sized-node-label Y))
21292110 (define Y1 (node-left-branch Y))
@@ -2163,13 +2144,15 @@ \section{Ausbalancieren durch Rotation}
21632144
21642145\mantrakomplexitaet *
21652146
2166- \noindent So richtig testen werden wir sie im nächsten Kapitel. Hier
2147+ \noindent So richtig testen werden wir \lstinline {balanced-search-tree-insert} und
2148+ \lstinline {make-balanced-node} erst im nächsten Kapitel. Hier
21672149eine Aufgabe zur Vorbereitung:
21682150
21692151\begin {aufgabeinline }
21702152 Mach Dir schomal ein paar Gedanken darüber, \emph {was } eigentlich
21712153 getestet werden müsste. Reicht es, die Funktion so zu testen wie
2172- \lstinline {search-tree-insert}?
2154+ \lstinline {search-tree-insert}, also nur zu testen, ob eingefügte
2155+ Elemente hinterher auch tatsächlich im Suchbaum sind?
21732156\end {aufgabeinline }
21742157
21752158\section* {Aufgaben }
0 commit comments