Gliederung Literatur Datenstrukturen und Algorithmen Herbert Kuchen Universität Münster Mo + Do 8:15 - 9:45, M1 Sommersemester 2011 1 Gliederung Literatur Gliederung 1. Einführung 2. Felder (Arrays) 2.1 Suchen 2.2 Sortieren 3. Dynamische Datenstrukturen 3.1 Lineare Liste 3.2 Baumstrukturen 4. Hashverfahren 5. Mustererkennung 6. Graphen 2 Gliederung Literatur Literatur • Th. Ottmann, P. Widmayer: Algorithmen und Datenstrukturen, Spektrum Akademischer Verlag, 2002, 693 S. • R. Sedgewick: Algorithmen, Pearson, 2002, 737 S. • R. Sedgewick: Algorithmen in Java, Addison Wesley, 2003 • T. Cormen, C. Leiserson, R. Rivest: Algorithmen – Eine Einführung, Pearson, 2007 • D. E. Knuth: The Art of Computer Programming, Bd. 3: Sorting and Searching, Addison Wesley, 1998 (bzw. 1973), 780 S. 3 1. Einführung zur Lösung eines Problems: • geeignete Datenstruktur • hierauf zugeschnittene Algorithmen (Rechenverfahren) • Implementierung in Programmiersprache 4 Algorithmus Merkmale: • endlich beschreibbares Rechenverfahren • jeder Schritt ausführbar • endlicher Zeit- und Platzbedarf häufig vorkommende Zusatzmerkmale: • determiniert (gleiches Ergebnis bei gleichen Eingaben) • deterministisch (nächster Schritt stets eindeutig bestimmt) Formalisierung: • durch Turingmaschine, Registermaschine, Lambda-Kalkül,. . . • durch Java-Programm, Haskell-Programm, . . . 5 Algorithmus (2) Eigenschaften eines Algorithmus • Korrektheit bezüglich Spezifikation (→ Beweis) • Effizienz bzgl. Zeit- und Platzbedarf häufiger Tradeoff • einfacher Algorithmus: schnelle Entwicklung, längere Laufzeit • ausgefeilter Algorithmus: längere Entwicklung, kürzere Laufzeit 6 Aufwand (Komplexität) • gemessen in Abh. von „Größe der Eingabe“ • im besten Fall (best case) • im schlechtesten Fall (worst case) • im Mittel (average case) • meist interessiert nur der „größenordnungsmäßige (asymptotische) Aufwand“ Vernachlässigung konstanter Faktoren 7 Notationen O(f ) = {g : IN → IN | ∃c1 > 0 ∃c2 > 0 ∀n ∈ IN g(n) ≤ c1 · f (n) + c2 } bzw. = {g : IN → IN | ∃c1 > 0 ∃n0 > 0 ∀n > n0 g(n) ≤ c1 · f (n)} Ω(f ) = {g : IN → IN | ∃c > 0 ∃n0 > 0 ∀n > n0 g(n) ≥ c ∗ f (n)} Θ(f ) = O(f ) ∩ Ω(f ) Sprechweisen: t(n) ∈ O(f ) : t(n) höchstens von der Größenordnung f t(n) ∈ Ω(f ) : ... t(n) ∈ Θ(f ) : . . . mindestens . . . genau . . . 8 Beispiel: Suche in Array public <T extends Comparable<T>> int search(T x, T[] a){ int i=0; while (i<a.length && x.compareTo(a[i]) != 0) i++; if (i<a.length) return i; else return -1;} • Größe der Eingabe: n := a.length • Anzahl der „elementaren Rechenschritte“ (Vergleich, arithm. Operation, . . . ) • im besten Fall: tB (n) = 5 (wenn x.compareTo(a[0]) ==0; für n > 0) also: tB (n) ∈ O(1) • im schlechtesten Fall: tW (n) = 4 ∗ n + 4 (wenn x nicht gefunden; beachte: && nicht strikt!) also: tW (n) ∈ O(n) (→ Induktion über n) 9 Aufwand im Mittel • bei Gleichverteilung, wenn gefunden, n > 0 tA (n) = n−1 P i=0 = = 1 n 1 n ∗ (4 ∗ i + 5) ∗ (4 n−1 P i=0 1 4n(n−1) n( 2 i+ n−1 P 5) i=0 + 5n) = 2(n − 1) + 5 = 2n + 3 also: tA (n) ∈ O(n) (bzw. Θ(n)) 10 Wichtige Komplexitätsklassen n log2 n 16 √ n · log2 n n2 n3 2n 64 256 4096 65536 4 1019 8 4 4096 262144 1.8 · n 64 6 384 1024 10 10240 ≈ 106 ≈ 109 10300 32 107 1012 1018 10300 ≈ 103 106 ≈ 20 ≈ 2 · ≈ ≈ heute schnellste Rechner: wenige PetaFlops = 1015 Gleitkomma-Operationen/Sekunde → 1018 Operationen erfordern ca. 3 Stunden • polynomielle Algorithmen (t(n) ∈ O(nc ) für c ∈ IN) gelten als (ggfs.) praxisrelevant (meist c ≤ 3) • exponentielle Algorithmen (t(n) ∈ O(c n ) für c> 1) gelten als praxisuntauglich 11