rekursion rekursive funktionen, korrektheit, terminierung, rekursion vs. iteration, sortieren
TRANSCRIPT
![Page 1: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/1.jpg)
Rekursion
Rekursive Funktionen, Korrektheit, Terminierung,
Rekursion vs. Iteration, Sortieren
![Page 2: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/2.jpg)
Mathematische Rekursion
o Viele mathematische Funktionen sind sehr natürlich rekursiv definierbar, d.h.
o die Funktion erscheint in ihrer eigenen Definition.
![Page 3: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/3.jpg)
Mathematische Rekursion
o Viele mathematische Funktionen sind sehr natürlich rekursiv definierbar, d.h.
o die Funktion erscheint in ihrer eigenen Definition.
1 , falls n ≤ 1
n! =
n · (n-1)! , falls n > 1
![Page 4: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/4.jpg)
Rekursion in C++
o modelliert oft direkt die mathematische Rekursionsformel
![Page 5: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/5.jpg)
Rekursion in C++
o modelliert oft direkt die mathematische Rekursionsformel.
// POST: return value is n!
unsigned int fac (const unsigned int n)
{
if (n <= 1) return 1;
return n * fac(n-1); // n > 1
}
![Page 6: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/6.jpg)
Unendliche Rekursion
o ist so leicht zu erzeugen wie eine unendliche Schleife,
o sollte aber genauso vermieden werden.
![Page 7: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/7.jpg)
Unendliche Rekursion
o ist so leicht zu erzeugen wie eine unendliche Schleife,
o sollte aber genauso vermieden werden.
void f()
{
f(); // calls f(), calls f(), calls f(),...
}
![Page 8: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/8.jpg)
Terminierung von rekursiven Funktionsaufrufen
Wie bei Schleifen brauchen wiro Fortschritt Richtung Terminierung
fac(n) :
terminiert sofort für n ≤ 1, andernfalls wird
die Funktion rekursiv mit Argument < n
aufgerufen.
![Page 9: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/9.jpg)
Terminierung von rekursiven Funktionsaufrufen
Wie bei Schleifen brauchen wiro Fortschritt Richtung Terminierung
“n wird mit jedem Aufruf kleiner.”
fac(n) :
terminiert sofort für n ≤ 1, andernfalls wird
die Funktion rekursiv mit Argument < n
aufgerufen.
![Page 10: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/10.jpg)
Auswertung rekursiver Funktionsaufrufe (z.B. fac(3))
// POST: return value is n!
unsigned int fac (const unsigned int n)
{
if (n <= 1) return 1;
return n * fac(n-1); // n > 1
}
![Page 11: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/11.jpg)
Auswertung rekursiver Funktionsaufrufe (z.B. fac(3))
// POST: return value is n!
unsigned int fac (const unsigned int n)
{ // n = 3
if (n <= 1) return 1;
return n * fac(n-1); // n > 1
}
Initialisierung des formalen Arguments mit dem Wert des Aufrufarguments
![Page 12: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/12.jpg)
Auswertung rekursiver Funktionsaufrufe (z.B. fac(3))
// POST: return value is n!
unsigned int fac (const unsigned int n)
{ // n = 3
if (n <= 1) return 1;
return n * fac(n-1); // n > 1
}
Ausführen des Funktionsrumpfs: Auswertung des Rückgabeausdrucks
![Page 13: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/13.jpg)
Auswertung rekursiver Funktionsaufrufe (z.B. fac(3))
// POST: return value is n!
unsigned int fac (const unsigned int n)
{ // n = 3
if (n <= 1) return 1;
return n * fac(n-1); // n > 1
}
Ausführen des Funktionsrumpfs: Rekursiver Aufruf von fac mit Aufrufargument n-1 == 2
![Page 14: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/14.jpg)
Auswertung rekursiver Funktionsaufrufe (z.B. fac(3))
// POST: return value is n!
unsigned int fac (const unsigned int n)
{ // n = 2
if (n <= 1) return 1;
return n * fac(n-1); // n > 1
}
Initialisierung des formalen Arguments mit dem Wert des Aufrufarguments
![Page 15: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/15.jpg)
Initialisierung des formalen Arguments mit dem Wert des Aufrufarguments
Auswertung rekursiver Funktionsaufrufe (z.B. fac(3))
// POST: return value is n!
unsigned int fac (const unsigned int n)
{ // n = 2
if (n <= 1) return 1;
return n * fac(n-1); // n > 1
} Es gibt jetzt zwei n ! Das von fac (3), und das von fac (2)
![Page 16: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/16.jpg)
Auswertung rekursiver Funktionsaufrufe (z.B. fac(3))
// POST: return value is n!
unsigned int fac (const unsigned int n)
{ // n = 2
if (n <= 1) return 1;
return n * fac(n-1); // n > 1
} Wir nehmen das Argument des aktuellen Aufrufs, fac (2)
Initialisierung des formalen Arguments mit dem Wert des Aufrufarguments
![Page 17: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/17.jpg)
Der Aufrufstapel
Bei Auswertung jedes Funktionsaufrufs:o Wert des Aufrufarguments kommt auf
einen Stapel (erst n = 3, dann n = 2,...)o es wird stets mit dem obersten Wert
gearbeiteto nach Ende des Funktionsaufrufs wird
der oberste Wert vom Stapel gelöscht
![Page 18: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/18.jpg)
Der Aufrufstapel
Bei Auswertung jedes Funktionsaufrufs:o Wert des Aufrufarguments kommt auf
einen Stapel (erst n = 3, dann n = 2,...)o es wird stets mit dem obersten Wert
gearbeiteto nach Ende eines Funktionsaufrufs wird
der oberste Wert vom Stapel gelöscht
Bei mehreren Argumenten analog (alle kommen auf den Stapel, wir arbeiten jeweils mit der obersten Version jedes Arguments)
![Page 19: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/19.jpg)
Grösster gemeinsamer Teiler
Euklidischer Algorithmuso findet den grössten gemeinsamen
Teiler gcd (a, b) zweier natürlicher Zahlen a und b
![Page 20: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/20.jpg)
Grösster gemeinsamer Teiler
Euklidischer Algorithmuso findet den grössten gemeinsamen
Teiler gcd (a, b) zweier natürlicher Zahlen a und b
o basiert auf folgendem Lemma (Beweis im Skript):
gcd (a, b) = gcd (b, a mod b) für b > 0 .
![Page 21: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/21.jpg)
Grösster gemeinsamer Teiler// POST: return value is the greatest common
// divisor of a and b
unsigned int gcd
(const unsigned int a, const unsigned int b)
{
if (b == 0) return a;
return gcd(b, a % b); // b != 0
}
![Page 22: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/22.jpg)
Grösster gemeinsamer Teiler// POST: return value is the greatest common
// divisor of a and b
unsigned int gcd
(const unsigned int a, const unsigned int b)
{
if (b == 0) return a;
return gcd(b, a % b); // b != 0
}
Korrektheit: gcd (a, 0) = a gcd (a, b) = gcd (b, a mod b), b > 0
Lemma!
![Page 23: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/23.jpg)
Grösster gemeinsamer Teiler// POST: return value is the greatest common
// divisor of a and b
unsigned int gcd
(const unsigned int a, const unsigned int b)
{
if (b == 0) return a;
return gcd(b, a % b); // b != 0
}
Terminierung: a mod b < b , also wird b in jedem rekursiven Aufruf kleiner.
![Page 24: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/24.jpg)
Grösster gemeinsamer Teiler// POST: return value is the greatest common
// divisor of a and b
unsigned int gcd
(const unsigned int a, const unsigned int b)
{
if (b == 0) return a;
return gcd(b, a % b); // b != 0
}
Korrektheit und Terminierung müssen bei rekursiven Funktionen stets separat bewiesen werden!
![Page 25: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/25.jpg)
Fibonacci-Zahlen
o F0 := 0
o F1 := 1
o Fn := Fn-1 + Fn-2 , n > 1
![Page 26: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/26.jpg)
Fibonacci-Zahlen
o F0 := 0
o F1 := 1
o Fn := Fn-1 + Fn-2 , n > 1
0, 1, 1, 2, 3, 5, 8, 13, 21, ...
![Page 27: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/27.jpg)
Fibonacci-Zahlen
o F0 := 0
o F1 := 1
o Fn := Fn-1 + Fn-2 , n > 1
0, 1, 1, 2, 3, 5, 8, 13, 21, ...
![Page 28: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/28.jpg)
Fibonacci-Zahlen// POST: return value is the n-th// Fibonacci number F_nunsigned int fib (const unsigned int n){ if (n == 0) return 0; if (n == 1) return 1; return fib(n-1) + fib(n-2); // n > 1}
![Page 29: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/29.jpg)
Fibonacci-Zahlen// POST: return value is the n-th// Fibonacci number F_nunsigned int fib (const unsigned int n){ if (n == 0) return 0; if (n == 1) return 1; return fib(n-1) + fib(n-2); // n > 1}
Korrektheit und Terminierung sind klar.
![Page 30: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/30.jpg)
Fibonacci-Zahlen// POST: return value is the n-th// Fibonacci number F_nunsigned int fib (const unsigned int n){ if (n == 0) return 0; if (n == 1) return 1; return fib(n-1) + fib(n-2); // n > 1}
Laufzeit:
fib (50) dauert “ewig”, denn es berechnet
F48 2-mal, F47 3-mal, F46 5-mal,
F45 8-mal, F44 13-mal, ...
![Page 31: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/31.jpg)
Rekursion und Iteration
Rekursion kann im Prinzip ersetzt werdendurcho Iteration (Schleifen) undo expliziten Aufrufstapel (z.B. Feld).
Oft sind direkte rekursive Formulierungen ein-
facher, aber manchmal auch weniger effizient.
![Page 32: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/32.jpg)
Endrekursion
Eine Funktion ist endrekursiv, wenn sie genau einen rekursiven Aufruf ganz am Ende enthält.
![Page 33: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/33.jpg)
Endrekursion
Eine Funktion ist endrekursiv, wenn sie genau einen rekursiven Aufruf ganz am Ende enthält.
// POST: return value is the greatest common// divisor of a and bunsigned int gcd (const unsigned int a, const unsigned int b){ if (b == 0) return a; return gcd(b, a % b); // b != 0}
![Page 34: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/34.jpg)
Endrekursion
o ist leicht iterativ zu schreiben.
// POST: return value is the greatest common divisor of a and b
unsigned int gcd2 (unsigned int a, unsigned int b)
{
while (b != 0) {
unsigned int a_prev = a;
a = b;
b = a_prev % b;
}
return a;
}
![Page 35: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/35.jpg)
Endrekursion
o ist leicht iterativ zu schreiben.
// POST: return value is the greatest common divisor of a and b
unsigned int gcd2 (unsigned int a, unsigned int b)
{
while (b != 0) {
unsigned int a_prev = a;
a = b;
b = a_prev % b;
}
return a;
}
“(a,b) (b, a mod b)”
![Page 36: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/36.jpg)
Endrekursion
o ist leicht iterativ zu schreiben.
// POST: return value is the greatest common divisor of a and b
unsigned int gcd2 (unsigned int a, unsigned int b)
{
while (b != 0) {
unsigned int a_prev = a;
a = b;
b = a_prev % b;
}
return a;
}
“(a,b) (b, a mod b)”
![Page 37: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/37.jpg)
Endrekursion
o ist leicht iterativ zu schreiben.
// POST: return value is the greatest common divisor of a and b
unsigned int gcd2 (unsigned int a, unsigned int b)
{
while (b != 0) {
unsigned int a_prev = a;
a = b;
b = a_prev % b;
}
return a;
}
“(a,b) (b, a mod b)”
![Page 38: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/38.jpg)
Endrekursion
o ist leicht iterativ zu schreiben.
// POST: return value is the greatest common divisor of a and b
unsigned int gcd2 (unsigned int a, unsigned int b)
{
while (b != 0) {
unsigned int a_prev = a;
a = b;
b = a_prev % b;
}
return a;
}
“(a,b) (b, a mod b)”
...aber die rekursive Version is lesbarer und (fast) genauso effizient.
![Page 39: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/39.jpg)
Fibonacci-Zahlen iterativ
Idee:o berechne jede Zahl genau einmal,
in der Reihenfolge F0 , F1 , F2 , F3 , ...o speichere die jeweils letzten
beiden berechneten Zahlen (Variablen a, b), dann kann die nächste Zahl durch eine Addition erhalten werden.
![Page 40: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/40.jpg)
Fibonacci-Zahlen iterativ// POST: return value is the n-th Fibonacci number F_nunsigned int fib2 (const unsigned int n){ if (n == 0) return 0; if (n <= 2) return 1; unsigned int a = 1; // F_1 unsigned int b = 1; // F_2 for (unsigned int i = 3; i <= n; ++i) { unsigned int a_prev = a; // F_{i-2} a = b; // F_{i-1} b += a_prev; // F_{i-1} += F_{i-2} -> F_i } return b;}
![Page 41: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/41.jpg)
Fibonacci-Zahlen iterativ// POST: return value is the n-th Fibonacci number F_nunsigned int fib2 (const unsigned int n){ if (n == 0) return 0; if (n <= 2) return 1; unsigned int a = 1; // F_1 unsigned int b = 1; // F_2 for (unsigned int i = 3; i <= n; ++i) { unsigned int a_prev = a; // F_{i-2} a = b; // F_{i-1} b += a_prev; // F_{i-1} += F_{i-2} -> F_i } return b;} “( Fi-2 , Fi-1 ) ( Fi-1 , Fi )”
a b
![Page 42: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/42.jpg)
Fibonacci-Zahlen iterativ// POST: return value is the n-th Fibonacci number F_nunsigned int fib2 (const unsigned int n){ if (n == 0) return 0; if (n <= 2) return 1; unsigned int a = 1; // F_1 unsigned int b = 1; // F_2 for (unsigned int i = 3; i <= n; ++i) { unsigned int a_prev = a; // F_{i-2} a = b; // F_{i-1} b += a_prev; // F_{i-1} += F_{i-2} -> F_i } return b;} “( Fi-2 , Fi-1 ) ( Fi-1 , Fi )”
a b
![Page 43: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/43.jpg)
Fibonacci-Zahlen iterativ// POST: return value is the n-th Fibonacci number F_nunsigned int fib2 (const unsigned int n){ if (n == 0) return 0; if (n <= 2) return 1; unsigned int a = 1; // F_1 unsigned int b = 1; // F_2 for (unsigned int i = 3; i <= n; ++i) { unsigned int a_prev = a; // F_{i-2} a = b; // F_{i-1} b += a_prev; // F_{i-1} += F_{i-2} -> F_i } return b;} “( Fi-2 , Fi-1 ) ( Fi-1 , Fi )”
a b
![Page 44: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/44.jpg)
Fibonacci-Zahlen iterativ// POST: return value is the n-th Fibonacci number F_nunsigned int fib2 (const unsigned int n){ if (n == 0) return 0; if (n <= 2) return 1; unsigned int a = 1; // F_1 unsigned int b = 1; // F_2 for (unsigned int i = 3; i <= n; ++i) { unsigned int a_prev = a; // F_{i-2} a = b; // F_{i-1} b += a_prev; // F_{i-1} += F_{i-2} -> F_i } return b;} “( Fi-2 , Fi-1 ) ( Fi-1 , Fi )”
a b
sehr schnell auch bei fib2(50)
![Page 45: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/45.jpg)
Die Ackermann-Funktion
n + 1 , falls m = 0
A (m, n) = A (m-1, 1) , falls m > 0, n = 0
A (m-1, A (m, n-1)) , falls m > 0, n > 0
![Page 46: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/46.jpg)
Die Ackermann-Funktion
n + 1 , falls m = 0
A (m, n) = A (m-1, 1) , falls m > 0, n = 0 A (m-1, A (m, n-1)) , falls m > 0, n > 0
o ist berechenbar, aber nicht primitiv rekursiv (man dachte Anfang des 20. Jahrhunderts, dass es diese Kombination gar nicht gibt)
o wächst extrem schnell
![Page 47: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/47.jpg)
Die Ackermann-Funktion// POST: return value is the Ackermann function
// value A(m,n)
unsigned int A
(const unsigned int m, const unsigned int n) {
if (m == 0) return n+1;
if (n == 0) return A(m-1,1);
return A(m-1, A(m, n-1));
}
![Page 48: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/48.jpg)
Die Ackermann-Funktion
0 1 2 3 ... n
0 1 2 3 4 ... n+1
1
2
3
4
m
n
![Page 49: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/49.jpg)
Die Ackermann-Funktion
0 1 2 3 ... n
0 1 2 3 4 ... n+1
1 2 3 4 5 ... n+2
2
3
4
m
n
![Page 50: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/50.jpg)
Die Ackermann-Funktion
0 1 2 3 ... n
0 1 2 3 4 ... n+1
1 2 3 4 5 ... n+2
2 3 5 7 9 ...2n+3
3
4
m
n
![Page 51: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/51.jpg)
Die Ackermann-Funktion
0 1 2 3 ... n
0 1 2 3 4 ... n+1
1 2 3 4 5 ... n+2
2 3 5 7 9 ...2n+3
3 5 13 29 61 ... 2n+3-3
4
m
n
![Page 52: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/52.jpg)
2
22 ...
-3
Die Ackermann-Funktion
0 1 2 3 ... n
0 1 2 3 4 ... n+1
1 2 3 4 5 ... n+2
2 3 5 7 9 ...2n+3
3 5 13 29 61 ... 2n+3-3
4 13 65533
265536-3 2 -3
...
m
n
265536
Turm von n+3 Zweierpotenzen
![Page 53: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/53.jpg)
2
22 ...
-3
Die Ackermann-Funktion
0 1 2 3 ... n
0 1 2 3 4 ... n+1
1 2 3 4 5 ... n+2
2 3 5 7 9 ...2n+3
3 5 13 29 61 ... 2n+3-3
4 13 65533
265536-3 2 -3
...
m
n
265536
nicht mehr praktisch berechenbar
![Page 54: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/54.jpg)
Die Ackermann-Funktion - Moral
o Rekursion ist sehr mächtig...o ... aber auch gefährlich:
![Page 55: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/55.jpg)
Die Ackermann-Funktion - Moral
o Rekursion ist sehr mächtig...o ... aber auch gefährlich:
Es ist leicht, harmlos aussehende rekursive Funktionen hinzuschreiben, die theoretisch korrekt sind und terminieren, praktisch aber jeden Berechenbarkeitsrahmen sprengen.
![Page 56: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/56.jpg)
Sortieren
Wie schnell kann man n Zahlen (oder Wörter,...) aufsteigend sortieren?
![Page 57: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/57.jpg)
Sortieren
Wie schnell kann man n Zahlen (oder Wörter,...) aufsteigend sortieren?
Wir haben in den Übungen bereits sortiert, uns aber keine Gedanken über die Effizienz gemacht
![Page 58: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/58.jpg)
Sortieren
Wie schnell kann man n Zahlen (oder Wörter,...) aufsteigend sortieren?
Wir haben in den Übungen bereits sortiert, uns aber keine Gedanken über die Effizienz gemacht
Das holen wir jetzt nach, denn Sortieren ist eine der grundlegenden Operationen in der Informatik
![Page 59: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/59.jpg)
Minimum-sort
ist ein sehr einfaches Sortierverfahren
haben einige wahrscheinlich in den Übungen implementiert
![Page 60: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/60.jpg)
Minimum-sort
ist ein sehr einfaches Sortierverfahren
haben einige wahrscheinlich in den Übungen implementiert
8 6 2 5 4 1 7 3
Finde die kleinste Zahl...
![Page 61: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/61.jpg)
Minimum-sort
ist ein sehr einfaches Sortierverfahren
haben einige wahrscheinlich in den Übungen implementiert
8 6 2 5 4 1 7 3
...und vertausche sie mit der ersten Zahl.
1 6 2 5 4 8 7 3
![Page 62: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/62.jpg)
Minimum-sort
ist ein sehr einfaches Sortierverfahren
haben einige wahrscheinlich in den Übungen implementiert
1 6 2 5 4 8 7 3
Finde die kleinste Zahl...
![Page 63: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/63.jpg)
Minimum-sort
ist ein sehr einfaches Sortierverfahren
haben einige wahrscheinlich in den Übungen implementiert
1 6 2 5 4 8 7 3
...und vertausche sie mit der ersten Zahl.
1 2 6 5 4 8 7 3
![Page 64: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/64.jpg)
Minimum-sort
ist ein sehr einfaches Sortierverfahren
haben einige wahrscheinlich in den Übungen implementiert
1 2 6 5 4 8 7 3
Finde die kleinste Zahl...
![Page 65: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/65.jpg)
Minimum-sort
ist ein sehr einfaches Sortierverfahren
haben einige wahrscheinlich in den Übungen implementiert
1 2 6 5 4 8 7 3
Finde die kleinste Zahl...
usw....
![Page 66: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/66.jpg)
Minimum-sort// PRE: [first, last) is a valid range// POST: the elements *p, p in [first, last) are in // ascending ordervoid minimum_sort (int* first, int* last) { for (int* p = first; p != last; ++p) { // find minimum in nonempty range described by [p, last) int* p_min = p; // pointer to current minimum int* q = p; // pointer to current element while (++q != last) if (*q < *p_min) p_min = q; // interchange *p with *p_min std::iter_swap (p, p_min); }}
1 2 6 5 4 8 7 3
Finde die kleinste Zahl...
p last
![Page 67: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/67.jpg)
Minimum-sort// PRE: [first, last) is a valid range// POST: the elements *p, p in [first, last) are in // ascending ordervoid minimum_sort (int* first, int* last) { for (int* p = first; p != last; ++p) { // find minimum in nonempty range described by [p, last) int* p_min = p; // pointer to current minimum int* q = p; // pointer to current element while (++q != last) if (*q < *p_min) p_min = q; // interchange *p with *p_min std::iter_swap (p, p_min); }}
1 2 6 5 4 8 7 3
..und vertausche sie mit der ersten Zahl
p p_min
![Page 68: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/68.jpg)
Minimum-sort// PRE: [first, last) is a valid range// POST: the elements *p, p in [first, last) are in // ascending ordervoid minimum_sort (int* first, int* last) { for (int* p = first; p != last; ++p) { // find minimum in nonempty range described by [p, last) int* p_min = p; // pointer to current minimum int* q = p; // pointer to current element while (++q != last) if (*q < *p_min) p_min = q; // interchange *p with *p_min std::iter_swap (p, p_min); }}
1 2 3 5 4 8 7 6
..und vertausche sie mit der ersten Zahl
p p_min
![Page 69: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/69.jpg)
Minimum-sort// PRE: [first, last) is a valid range// POST: the elements *p, p in [first, last) are in // ascending ordervoid minimum_sort (int* first, int* last) { for (int* p = first; p != last; ++p) { // find minimum in nonempty range described by [p, last) int* p_min = p; // pointer to current minimum int* q = p; // pointer to current element while (++q != last) if (*q < *p_min) p_min = q; // interchange *p with *p_min std::iter_swap (p, p_min); }}
1 2 3 5 4 8 7 6
..und vertausche sie mit der ersten Zahl
p p_min
#include<algorithm>
![Page 70: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/70.jpg)
Minimum-sort: Laufzeit
hängt von der Plattform ab.
![Page 71: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/71.jpg)
Minimum-sort: Laufzeit
hängt von der Plattform ab Trotzdem gibt es ein
plattformunab-hängiges Laufzeitmass:Anzahl der Vergleiche *q <
*p_min
![Page 72: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/72.jpg)
Minimum-sort: Laufzeit
hängt von der Plattform ab Trotzdem gibt es ein plattformunab-
hängiges Laufzeitmass:
Anzahl anderer Operationen ist wesentlich kleiner oder proportional dazu
Anzahl der Vergleiche *q < *p_min
![Page 73: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/73.jpg)
Minimum-sort: Laufzeit// PRE: [first, last) is a valid range// POST: the elements *p, p in [first, last) are in // ascending ordervoid minimum_sort (int* first, int* last) { for (int* p = first; p != last; ++p) { // find minimum in nonempty range described by [p, last) int* p_min = p; // pointer to current minimum int* q = p; // pointer to current element while (++q != last) if (*q < *p_min) p_min = q; // interchange *p with *p_min std::iter_swap (p, p_min); }}
n - 1 + n - 2 + ... + 1 Vergleiche = n (n -1) / 2
n Elemente
![Page 74: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/74.jpg)
Minimum-sort: Laufzeit// PRE: [first, last) is a valid range// POST: the elements *p, p in [first, last) are in // ascending ordervoid minimum_sort (int* first, int* last) { for (int* p = first; p != last; ++p) { // find minimum in nonempty range described by [p, last) int* p_min = p; // pointer to current minimum int* q = p; // pointer to current element while (++q != last) if (*q < *p_min) p_min = q; // interchange *p with *p_min std::iter_swap (p, p_min); }}
jeweils ≤ n Operationen (wesentlich kleiner)
n Elemente
![Page 75: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/75.jpg)
Minimum-sort: Laufzeit// PRE: [first, last) is a valid range// POST: the elements *p, p in [first, last) are in // ascending ordervoid minimum_sort (int* first, int* last) { for (int* p = first; p != last; ++p) { // find minimum in nonempty range described by [p, last) int* p_min = p; // pointer to current minimum int* q = p; // pointer to current element while (++q != last) if (*q < *p_min) p_min = q; // interchange *p with *p_min std::iter_swap (p, p_min); }}
höchstens n (n -1) / 2 Operationen (proportional)
n Elemente
![Page 76: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/76.jpg)
Minimum-sort: Laufzeit// PRE: [first, last) is a valid range// POST: the elements *p, p in [first, last) are in // ascending ordervoid minimum_sort (int* first, int* last) { for (int* p = first; p != last; ++p) { // find minimum in nonempty range described by [p, last) int* p_min = p; // pointer to current minimum int* q = p; // pointer to current element while (++q != last) if (*q < *p_min) p_min = q; // interchange *p with *p_min std::iter_swap (p, p_min); }}
n (n -1) / 2 + n Operationen (proportional)
n Elemente
![Page 77: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/77.jpg)
Minimum-sort: Laufzeit
Auf “jeder” Plattform: Gesamtlaufzeit ist proportional zur Zeit, die mit den Vergleichen *q < *p_min verbracht wird
![Page 78: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/78.jpg)
Minimum-sort: Laufzeit
Auf “jeder” Plattform: Gesamtlaufzeit ist proportional zur Zeit, die mit den Vergleichen *q < *p_min verbracht wird
Diese wiederum ist proportional zur Anzahl n (n – 1) / 2 dieser Vergleiche
![Page 79: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/79.jpg)
Minimum-sort: Laufzeit
Auf “jeder” Plattform: Gesamtlaufzeit ist proportional zur Zeit, die mit den Vergleichen *q < *p_min verbracht wird
Diese wiederum ist proportional zur Anzahl n (n – 1) / 2 dieser Vergleiche
Anzahl der Vergleiche ist deshalb ein gutes Mass für die Gesamtlaufzeit!
![Page 80: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/80.jpg)
Minimum-sort: Laufzeit (Mac)auf zufälliger Eingabe
n 100,000
200,000
400,000
800,000
1,600,000
Gcomp (MilliardenVergleiche)
5 20 80 320 1280
Laufzeit inmin : s
0:15 1:05 4:26 15:39 64:22
Laufzeit / GComp (s)
3.0 3.25 3.325 2.93 3.01
![Page 81: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/81.jpg)
Minimum-sort: Laufzeit (Mac)auf zufälliger Eingabe
n 100,000
200,000
400,000
800,000
1,600,000
Gcomp (MilliardenVergleiche)
5 20 80 320 1280
Laufzeit inmin : s
0:15 1:05 4:26 15:39 64:22
Laufzeit / GComp (s)
3.0 3.25 3.325 2.93 3.01
n 100,000
200,000
400,000
800,000
1,600,000
Gcomp (MilliardenVergleiche)
5 20 80 320 1280
Laufzeit inmin : s
0:1 1:
Laufzeit / GComp (s)
Ungefähr konstant! Anzahl Vergleiche ist ein gutes Laufzeitmass!
![Page 82: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/82.jpg)
Minimum-sort: Laufzeit (Mac)auf zufälliger Eingabe
n 100,000
200,000
400,000
800,000
1,600,000
Gcomp (MilliardenVergleiche)
5 20 80 320 1280
Laufzeit inmin : s
0:15 1:05 4:26 15:39 64:22
Laufzeit / GComp (s)
3.0 3.25 3.325 2.93 3.01
n 100,000
200,000
400,000
800,000
1,600,000
Gcomp (MilliardenVergleiche)
5 20 80 320 1280
Laufzeit inmin : s
0:1 1:
Laufzeit / GComp (s)
D.h.: für 10,000,000 Zahlen bräuchte Minimum-sort ca. 2 Tage!
![Page 83: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/83.jpg)
Merge-sort
ein schnelleres (und rekursives) Sortierverfahren
folgt dem Paradigma “Teile und Herrsche” (Divide & Conquer)
Teile das Problem in kleinere Teilprobleme des gleichen Typs auf, löse diese rekursiv, und berechne die Gesamtlösung aus den Lösungen der Teilprobleme
![Page 84: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/84.jpg)
Merge-sort
Analogie: Sortieren eines Kartenstapels
Karten sind mit Zahlen beschriftet
![Page 85: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/85.jpg)
Merge-sort: Teile
Analogie: Sortieren eines Kartenstapels
Karten sind mit Zahlen beschriftetSchritt 1: Teile den Stapel in zwei gleich grosse Stapel
![Page 86: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/86.jpg)
Merge-sort: Teile
Analogie: Sortieren eines Kartenstapels
Karten sind mit Zahlen beschriftetSchritt 2: Sortiere beide Stapel getrennt
![Page 87: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/87.jpg)
Merge-sort: Herrsche
Analogie: Sortieren eines Kartenstapels
Karten sind mit Zahlen beschriftetSchritt 3: Mische die beiden sortierten Stapel zu einem sortierten Stapel: lege dazu jeweils die kleinere der beiden oberen Karten umgedreht auf einen neuen Stapel
![Page 88: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/88.jpg)
Merge-sort in C++// PRE: [first, last) is a valid range// POST: the elements *p, p in [first, last) are in // ascending ordervoid merge_sort (int* first, int* last) { int n = last - first; if (n <= 1) return; // nothing to do int* middle = first + n/2; merge_sort (first, middle); // sort first half merge_sort (middle, last); // sort second half merge (first, middle, last); // merge both halfs}
![Page 89: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/89.jpg)
Merge-sort in C++: Teile// PRE: [first, last) is a valid range// POST: the elements *p, p in [first, last) are in // ascending ordervoid merge_sort (int* first, int* last) { int n = last - first; if (n <= 1) return; // nothing to do int* middle = first + n/2; merge_sort (first, middle); // sort first half merge_sort (middle, last); // sort second half merge (first, middle, last); // merge both halfs}
n / 2Elemente (n / 2 abgerundet)
n / 2Elemente (n / 2 aufgerundet)
![Page 90: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/90.jpg)
Merge-sort in C++: Herrsche// PRE: [first, last) is a valid range// POST: the elements *p, p in [first, last) are in // ascending ordervoid merge_sort (int* first, int* last) { int n = last - first; if (n <= 1) return; // nothing to do int* middle = first + n/2; merge_sort (first, middle); // sort first half merge_sort (middle, last); // sort second half merge (first, middle, last); // merge both halfs}
Diese Funktion übernimmt das Mischen zu einem Stapel
![Page 91: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/91.jpg)
Die Merge-Funktion// PRE: [first, middle), [middle, last) are valid ranges; in// both of them, the elements are in ascending ordervoid merge (int* first, int* middle, int* last){ int n = last - first; // total number of cards int* deck = new int[n]; // new deck to be built int* left = first; // top card of left deck int* right = middle; // top card of right deck for (int* d = deck; d != deck + n; ++d) // put next card onto new deck if (left == middle) *d = *right++; // left deck is empty else if (right == last) *d = *left++; // right deck is empty else if (*left < *right) *d = *left++; // smaller top card left else *d = *right++; // smaller top card right // copy new deck back into [first, last) int *d = deck; while (first != middle) *first++ = *d++; while (middle != last) *middle++ = *d++;
delete[] deck;}
![Page 92: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/92.jpg)
Merge-sort: Laufzeit
ist wieder proportional zur Anzahl der Vergleiche *left < *right (das muss man aber nicht sofort sehen)
Alle Vergleiche werden von der Funktion merge durchgeführt
![Page 93: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/93.jpg)
Merge-sort: Laufzeit
ist wieder proportional zur Anzahl der Vergleiche *left < *right (das muss man aber nicht sofort sehen)
Alle Vergleiche werden von der Funktion merge durchgeführtBeim Mischen zweier Stapel zu einem Stapel der Grösse n braucht merge höchstens n -1 Vergleiche (maximal einer für jede Karte des neuen Stapels, ausser der letzten)
![Page 94: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/94.jpg)
Merge-sort: Laufzeit
Satz:
Die Funktion merge_sort sortiert eine Folge von n ≥ 1 Zahlen mit höchstens (n – 1) log2n
Vergleichen zwischen zwei Zahlen.
![Page 95: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/95.jpg)
Merge-sort: Laufzeit
Beweis:
T (n ) sei die maximal mögliche Anzahl von Vergleichen zwischen Zahlen, die beim Sortieren von n Zahlen mit merge_sort auftreten können.
![Page 96: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/96.jpg)
Merge-sort: Laufzeit
Beweis:
o T (0) = T (1) = 0
T (n ) sei die maximal mögliche Anzahl von Vergleichen zwischen Zahlen, die beim Sortieren von n Zahlen mit merge_sort auftreten können.
![Page 97: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/97.jpg)
Merge-sort: Laufzeit
Beweis:
o T (0) = T (1) = 0o T (2) = 1
T (n ) sei die maximal mögliche Anzahl von Vergleichen zwischen Zahlen, die beim Sortieren von n Zahlen mit merge_sort auftreten können.
![Page 98: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/98.jpg)
Merge-sort: Laufzeit
Beweis:
o T (0) = T (1) = 0o T (2) = 1o T (3) = 2
T (n ) sei die maximal mögliche Anzahl von Vergleichen zwischen Zahlen, die beim Sortieren von n Zahlen mit merge_sort auftreten können.
![Page 99: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/99.jpg)
Merge-sort: Laufzeit
Beweis:
o T (n ) ≤ T (n /2) + T (n /2) + n -1 für n ≥ 2
T (n ) sei die maximal mögliche Anzahl von Vergleichen zwischen Zahlen, die beim Sortieren von n Zahlen mit merge_sort auftreten können.
![Page 100: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/100.jpg)
Merge-sort: Laufzeit
Beweis:
o T (n ) ≤ T (n /2) + T (n /2) + n -1 für n ≥ 2
T (n ) sei die maximal mögliche Anzahl von Vergleichen zwischen Zahlen, die beim Sortieren von n Zahlen mit merge_sort auftreten können.
maximale Anzahl im linken Stapel
maximale Anzahl im rechten Stapel
maximale Anzahl beim Mischen
![Page 101: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/101.jpg)
Merge-sort: Laufzeit
o Mit vollständiger Induktion beweisen wir nun (für n ≥ 1) die AussageT (n ) ≤ (n – 1)
log2n
![Page 102: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/102.jpg)
Merge-sort: Laufzeit
o Mit vollständiger Induktion beweisen wir nun (für n ≥ 1) die Aussage
o n=1: T (1) = 0 = (1 - 0) log21
T (n ) ≤ (n – 1) log2n
![Page 103: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/103.jpg)
Merge-sort: Laufzeit
o Sei nun n ≥ 2 und gelte die Aussage für alle Werte in {1,...,n -1} (Induktionsannahme)
![Page 104: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/104.jpg)
Merge-sort: Laufzeit
o Sei nun n ≥ 2 und gelte die Aussage für alle Werte in {1,...,n -1} (Induktionsannahme)
o Zu zeigen ist, dass die Aussage dann auch für n gilt (Induktionsschritt)
![Page 105: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/105.jpg)
Merge-sort: Laufzeit
o Es gilt T (n ) ≤ T (n /2) + T (n /2) + n -1
≥1 und < n
![Page 106: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/106.jpg)
Merge-sort: Laufzeit
o Es gilt T (n ) ≤ T (n /2) + T (n /2) + n -1 ≤ (n /2 -1) log2 n /2 +
(n /2 -1) log2 n /2 + n -1
Induktionsannahme
![Page 107: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/107.jpg)
Merge-sort: Laufzeit
o Es gilt T (n ) ≤ T (n /2) + T (n /2) + n -1 ≤ (n /2 -1) log2 n /2 +
(n /2 -1) log2 n /2 + n -1
≤ (n /2 -1) ( log2 n - 1) +
(n /2 -1) ( log2 n - 1 )+ n -1
Aufgabe 120
![Page 108: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/108.jpg)
Merge-sort: Laufzeit
o Es gilt T (n ) ≤ T (n /2) + T (n /2) + n -1 ≤ (n /2 -1) log2 n /2 +
(n /2 -1) log2 n /2 + n -1
≤ (n /2 -1) ( log2 n - 1) +
(n /2 -1) ( log2 n - 1 )+ n -1
= (n – 2) ( log2 n - 1) + n -1
![Page 109: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/109.jpg)
Merge-sort: Laufzeit
o Es gilt T (n ) ≤ T (n /2) + T (n /2) + n -1 ≤ (n /2 -1) log2 n /2 +
(n /2 -1) log2 n /2 + n -1
≤ (n /2 -1) ( log2 n - 1) +
(n /2 -1) ( log2 n - 1 )+ n -1
≤ (n – 1) ( log2 n - 1) + n -1
![Page 110: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/110.jpg)
Merge-sort: Laufzeit
o Es gilt T (n ) ≤ T (n /2) + T (n /2) + n -1 ≤ (n /2 -1) log2 n /2 +
(n /2 -1) log2 n /2 + n -1
≤ (n /2 -1) ( log2 n - 1) +
(n /2 -1) ( log2 n - 1 )+ n -1
≤ (n – 1) ( log2 n - 1) + n -1
= (n – 1) ( log2 n )
![Page 111: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/111.jpg)
Merge-sort: Laufzeit (PC)auf zufälliger Eingabe
n 100,000
200,000
400,000
800,000
1,600,000
Mcomp (MillionenVergleiche)
1.7 3.6 7.6 16 33.6
Laufzeit inms
46 93 190 390 834
Laufzeit / GComp (s)
27 25.8 25 24.4 25.1merge_sort braucht 8-mal mehr Zeit pro Vergleich als minimum_sort...
![Page 112: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/112.jpg)
Merge-sort: Laufzeit (PC)auf zufälliger Eingabe
n 100,000
200,000
400,000
800,000
1,600,000
Mcomp (MillionenVergleiche)
1.7 3.6 7.6 16 33.6
Laufzeit inms
46 93 190 390 834
Laufzeit / GComp (s)
27 25.8 25 24.4 25.1...ist aber aufgrund sehr viel weniger Vergleichen trotzdem sehr viel schneller!
> 1h bei minimum_sort
![Page 113: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/113.jpg)
Mit wievielen Vergleichen kann man n Zahlen sortieren?
minimum_sort: n(n-1)/2 merge_sort: ≤ (n – 1) ( log2 n ) optimal_sort: ???
![Page 114: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/114.jpg)
Mit wievielen Vergleichen kann man n Zahlen sortieren?
minimum_sort: n(n-1)/2 merge_sort: ≤ (n – 1) ( log2 n ) optimal_sort: ??? Satz: jedes vergleichsbasierte Sortierverfahren braucht mindestens log2 (n !) ≈ n log2 n – 1.44 n Vergleiche; also ist merge_sort fast optimal.
![Page 115: Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren](https://reader035.vdocuments.site/reader035/viewer/2022062312/55204d7549795902118ca839/html5/thumbnails/115.jpg)
Mit wievielen Vergleichen kann man n Zahlen sortieren?
minimum_sort: n(n-1)/2 merge_sort: ≤ (n – 1) ( log2 n ) optimal_sort: ???
Aber: Anzahl der Vergleiche ist nur bedingt geeignet zur Vorhersage praktischer Effizienz. quick_sort : braucht etwas mehr Vergleiche, ist aber schneller
Satz: jedes vergleichsbasierte Sortierverfahren braucht mindestens log2 (n !) ≈ n log2 n – 1.44 n Vergleiche; also ist merge_sort fast optimal.