Skip to content

Commit 0176db0

Browse files
committed
Noch mehr Seitenumbrüche.
1 parent 357e230 commit 0176db0

File tree

2 files changed

+50
-64
lines changed

2 files changed

+50
-64
lines changed

i1gem.tex

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -446,10 +446,10 @@ \section{Gemischte Daten als Ausgabe}
446446
Nun können wir eine Funktion schreiben, die ein beliebiges Tier
447447
akzeptiert und es füttert. Hier sind Kurzbeschreibung und Signatur:
448448
%
449-
\begin{aufgabe}
449+
\begin{lstlisting}
450450
; Tier füttern
451451
(: feed-animal (animal -> animal))
452-
\end{aufgabe}
452+
\end{lstlisting}
453453
%
454454
Die Funktion soll sich genauso verhalten wie \lstinline{feed-dillo}
455455
beziehungsweise \lstinline{feed-parrot}. Das können wir direkt als
@@ -531,10 +531,12 @@ \section{Die Lebensmittelampel}
531531
Manchmal ist allerdings der Zuckergehalt auch separat für Fruktose und
532532
Glukose angegeben.
533533

534-
Ein Computerprogramm könnte aber den Umgang erleichtern, indem es jede
535-
Angabe auf einer Lebensmittelpackung~-- Zucker in Gramm insgesamt,
534+
Ein Programm könnte aber den Umgang erleichtern, indem die
535+
Angaben auf einer Lebensmittelpackung~-- Zucker in Gramm insgesamt,
536536
Fruktose und Glukose separat sowie die Ampel~-- in die einheitliche
537-
Ampel-Form bringt. Schreiben wir also ein solches Programm. Zunächst
537+
Ampel-Form bringt.
538+
539+
Schreiben wir also ein solches Programm. Zunächst
538540
die Datenanalyse:
539541
%
540542
\begin{itemize}
@@ -810,7 +812,7 @@ \section{Die Lebensmittelampel}
810812
((> sugar-weight 12.5) "red"))))
811813
\end{lstlisting}
812814
%
813-
Zurück zu \lstinline{sugar-traffic-light}. Dort benutzen wir die
815+
Zurück zur Funktion \lstinline{sugar-traffic-light}. Dort benutzen wir die
814816
neu definierte Hilfsfunktion:
815817
%
816818
\begin{lstlisting}
@@ -823,8 +825,9 @@ \section{Die Lebensmittelampel}
823825
((string? sugar-content) ...))))
824826
\end{lstlisting}
825827
%
826-
Beim nächsten Zweig geht es um den Fall \lstinline{sugars}~--
827-
das sind zusammengesetzte Daten:
828+
Beim nächsten Zweig geht es um den Fall \lstinline{sugars}.
829+
Das sind zusammengesetzte Daten, wir schreiben in den Zweig dafür also
830+
die Schablone mit den Aufrufen der Selektoren:
828831
%
829832
\begin{lstlisting}
830833
(define sugar-traffic-light

i1tree.tex

Lines changed: 39 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -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}
805805
natü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

897891
In den Testfällen für \lstinline{tree-member?} haben wir immer den
898892
Baum \lstinline{tree4} vwerwendet, den wir direkt mit
899893
\lstinline{make-node} konstruiert haben. Dabei mussten wir selbst
900894
darauf 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.
904896
Wir 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}
938929
Seite~\pageref{cha:properties} werden wir zeigen, wie man Funktionen
939930
wie \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
%
999990
Es bleiben noch zwei Fälle, in denen der einzufügende Wert links
1000991
beziehungsweise 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
1002993
das erledigen die beiden rekursiven Aufrufe aus der Schablone. Der
1003994
jeweils andere Teilbaum bleibt so wie er ist:
1004995
%
@@ -1057,7 +1048,6 @@ \section{Suchbäume}
10571048
\lstinline{<} hinschreiben. Das nervt und ist jedesmal eine
10581049
Gelegenheit für einen Fehler, weil wir das vollkommen konsistent
10591050
machen müssen.
1060-
10611051
Wir wollen also versuchen, ohne diese zusätzlichen Parameter
10621052
auszukommen. Dazu benutzen wir einen Trick und packen die Funktionen
10631053
fü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
12451237
der 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
12481241
versuchen, das zu einer Formel zu verallgemeinern. Die Tiefe des
12491242
Baums 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}
12571250
vollständige Induktion anwenden nach der Anleitung in
12581251
Abschnitt~\ref{sec:nat-induction-ka} auf
12591252
Seite~\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
%
13991381
In 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
14021384
immmer \index{balancieren!von Suchbäumen}\textit{balanciert}.
14031385

14041386
Spätestens jetzt betreten wir einen Bereich der Programmierung, der in
@@ -1510,8 +1492,7 @@ \subsection{Größenannotierte Bäume}
15101492
diese 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
%
17101691
Wir machen aus
@@ -1993,6 +1974,8 @@ \section{Ausbalancieren durch Rotation}
19931974
Rotation ist etwas komplizierter, darum heißt sie "<doppelte">
19941975
Rotation, 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}
20051988
größer als der andere. Nehmen wir mal an, das ist $X$. Dann
20061989
vermindert eine einfache Rotation das Ungleichgewicht zwischen links
20071990
und rechts.
2008-
20091991
Wenn aber $Y$ größer ist $Z$, dann macht die einfache Rotation das
20101992
Ungleichgewicht \emph{größer}: Der eh größere Brocken $Y$ tut sich
20111993
dann auch noch mit $X$ zusammen, während der kleine Brocken $Z$ rechts
@@ -2100,7 +2082,7 @@ \section{Ausbalancieren durch Rotation}
21002082
gegenüber dem gerade behandelten Fall "<gespiegelt">. Auch der letzte
21012083
Fall fehlt noch: Der tritt dann ein, wenn der Baum kein exzessives
21022084
Ungleichgewicht aufweist. Dann könnten wir einfach
2103-
\lstinline{make-sized-node} benutzten.
2085+
\lstinline{make-sized-node} benutzen.
21042086
21052087
Hier 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
21672149
eine 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

Comments
 (0)