1 Informatik II: Datenstrukturen und Algorithmen Herbert Kuchen V4 + Ü2, WWU Münster, SS 2008 2 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 3 Literatur • Th. Ottmann, P. Widmayer: Algorithmen und Datenstrukturen, Spektrum Akad. Verlag, 2002 • R. Sedgewick: Algorithmen, Pearson, 2002 • 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) 4 1. Einführung zur Lösung eines Problems: • geeignete Datenstruktur • hierauf zugeschnittene Algorithmen (sprachunabhängige Rechenverfahren) • Implementierung in Programmiersprache Eigenschaften eines Algorithmus • Korrektheit (→ Beweis) • Effizienz bzgl. Zeit- und Platzbedarf häufiger Tradeoff • einfacher Algorithmus: schnelle Entwicklung, größere Laufzeit • ausgefeilter Algorithmus: längere Entwicklungszeit, kürzere Laufzeit 5 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 6 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 . . . 7 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) 8 Aufwand im Mittel • bei Gleichverteilung, wenn gefunden, n > 0 tA(n) = n−1 P i=0 = = 1 n 1 n ∗ (4 ∗ (4 ∗ i + 5) n−1 P i=0 1 4n(n−1) n( 2 i+ i=0 + 5n) = 2(n − 1) + 5 = 2n + 3 also: tA(n) ∈ O(n) (bzw. Θ(n)) n−1 P 5) 9 Wichtige Komplexitätsklassen 2 3 n √ n log2 n n · log2 n n n 2 n 16 4 64 256 4096 65536 4 64 6 384 4096 262144 1.8 · 1019 8 1024 10 10240 ≈ 106 ≈ 109 10300 32 106 ≈ 20 ≈ 2 · 107 ≈ 1012 ≈ 1018 10300 ≈ 103 heute schnellste Rechner: 1 TeraFlops = 1012 Gleitkomma-Operationen/Sekunde → 1018 Operationen erfordern 12 Tage 1.8 ∗ 1019 Operationen erfordern > 200 Tage daher: • polynomielle Algorithmen (t(n) ∈ O(nc) für c ∈ IN) gelten als (ggfs.) praxisrelevant (meist c ≤ 3) • exponentielle Algorithmen (t(n) ∈ O(cn) für c> 1) gelten als praxisuntauglich