1 Algorithmen und Datenstrukturen 1 Einleitung Im ersten Kapitel soll auf informeller Ebene anhand eines einfachen Beispiels der Begriff des Algorithmus sowie verschiedene Aspekte der Algorithmenanalyse eingeführt werden. Wichtige Punkte dabei sind die Darstellung eines Algorithmus in Pseudocode, Korrektheit eines Algorithmus, Schleifeninvarianten, Laufzeit eines Algorithmus, das zugrundeliegende Maschinenmodell, die Wachstumsordnung sowie die Entwurfsstrategie divide and conquer. 1 Einleitung TU Bergakademie Freiberg, WS 2005/06 2 Algorithmen und Datenstrukturen 1.1 Sortieren durch Einfügen (Insertion-Sort) Problembeschreibung: Eingabe: Eine Folge von n Zahlen ha1 , a2 , . . . , an i. Ausgabe: Umordnung ha01 , a02 , . . . , a0n i der Eingabefolge mit der Eigenschaft a01 ≤ a02 ≤ · · · ≤ a0n . Die Zahlen werden auch als Schlüssel (keys) bezeichnet; diese sind oft nur ein Bestandteil eines Datensatzes. Wir werden verschiedene Sortierverfahren kennenlernen, jedes wird durch einen Algorithmus ausgedrückt. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 3 Algorithmen und Datenstrukturen Darstellung von Algorithmen • Oft ist Umgangssprache am zweckmäßigsten (Kochrezepte, Bedienungsanleitungen) • Zu den präzisesten Darstellungen zählen die in einer Programmiersprache (Pascal, C, Java, . . . ). • Zwischenvariante: Pseudocode. ◦ Enthält genaue Angaben über Ablauf, aber auch umgangssprachliche Bestandteile. ◦ Dient der Vermittlung von Algorithmen an Menschen (im Gegensatz zu Maschinen) ◦ Softwaretechnische Aspekte wie Datenkapselung, Modularität, Fehlerbehandlung usw. werden dabei ignoriert. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 4 Algorithmen und Datenstrukturen Insertion-Sort Ein Algorithmus zur Sortierung einer kleinen Anzahl von Schlüsseln Vorgehen ähnlich der Sortierung eines Spielkartenblatts: • Am Anfang liegen die Karten des Blatts verdeckt auf dem Tisch. • Die Karten werden nacheinander aufgedeckt und an der korrekten Position in das Blatt, das in der Hand gehalten wird, eingefügt. • Um die Einfügestelle für eine neue Karte zu finden wird diese sukzessive (von links nach rechts) mit den bereits einsortierten Karten des Blattes verglichen. • Zu jedem Zeitpunkt sind die Karten in der Hand sortiert und bestehen aus den zuerst vom Tisch entnommenen Karten. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 5 Algorithmen und Datenstrukturen I NSERTION -S ORT(A) 1 for j ← 2 to length[A] 2 do key ← A[j] 3 Füge A[j] ein in die sortierte Folge A[1 . . j − 1]. 4 i←j−1 5 while i > 0 and A[i] > key 6 do A[i + 1] ← A[i] 7 i←i−1 8 A[i + 1] ← key Der Pseudocode für den Insertion-Sort Algorithmus ist durch obige Prozedur I NSERTION -S ORT gegeben, die als Eingabeparameter ein Feld A mit der zu sortierenden Folge erhält. Die Folge wird an Ort und Stelle (in place) sortiert. Nach Beendigung des Algorithmus enthält A die sortierte Folge. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 6 Algorithmen und Datenstrukturen Beispiel: 1 2 3 4 5 6 5 2 4 6 1 3 Ausführung von Insertion-Sort auf Eingabefeld A[1 . . 6]. Die Komponente, auf die der Index j zeigt“, ist rot eingefärbt. Blau eingfärbte Felder liegen im bereits ” sortierten Teilfeld A[1 . . j − 1]. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 6 Algorithmen und Datenstrukturen Beispiel: 1 2 3 4 5 6 5 2 4 6 1 3 Ausführung von Insertion-Sort auf Eingabefeld A[1 . . 6]. Die Komponente, auf die der Index j zeigt“, ist rot eingefärbt. Blau eingfärbte Felder liegen im bereits ” sortierten Teilfeld A[1 . . j − 1]. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 6 Algorithmen und Datenstrukturen Beispiel: 1 2 3 4 5 6 52 52 4 6 1 3 Ausführung von Insertion-Sort auf Eingabefeld A[1 . . 6]. Die Komponente, auf die der Index j zeigt“, ist rot eingefärbt. Blau eingfärbte Felder liegen im bereits ” sortierten Teilfeld A[1 . . j − 1]. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 6 Algorithmen und Datenstrukturen Beispiel: 1 2 3 4 5 6 52 52 4 6 1 3 Ausführung von Insertion-Sort auf Eingabefeld A[1 . . 6]. Die Komponente, auf die der Index j zeigt“, ist rot eingefärbt. Blau eingfärbte Felder liegen im bereits ” sortierten Teilfeld A[1 . . j − 1]. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 6 Algorithmen und Datenstrukturen Beispiel: 1 2 3 4 5 6 52 452 45 6 1 3 Ausführung von Insertion-Sort auf Eingabefeld A[1 . . 6]. Die Komponente, auf die der Index j zeigt“, ist rot eingefärbt. Blau eingfärbte Felder liegen im bereits ” sortierten Teilfeld A[1 . . j − 1]. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 6 Algorithmen und Datenstrukturen Beispiel: 1 2 3 4 5 6 52 452 54 6 1 3 Ausführung von Insertion-Sort auf Eingabefeld A[1 . . 6]. Die Komponente, auf die der Index j zeigt“, ist rot eingefärbt. Blau eingfärbte Felder liegen im bereits ” sortierten Teilfeld A[1 . . j − 1]. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 6 Algorithmen und Datenstrukturen Beispiel: 1 2 3 4 5 6 52 452 54 6 1 3 Ausführung von Insertion-Sort auf Eingabefeld A[1 . . 6]. Die Komponente, auf die der Index j zeigt“, ist rot eingefärbt. Blau eingfärbte Felder liegen im bereits ” sortierten Teilfeld A[1 . . j − 1]. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 6 Algorithmen und Datenstrukturen Beispiel: 1 2 3 4 5 6 251 245 45 56 16 3 Ausführung von Insertion-Sort auf Eingabefeld A[1 . . 6]. Die Komponente, auf die der Index j zeigt“, ist rot eingefärbt. Blau eingfärbte Felder liegen im bereits ” sortierten Teilfeld A[1 . . j − 1]. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 6 Algorithmen und Datenstrukturen Beispiel: 1 2 3 4 5 6 251 245 45 56 61 3 Ausführung von Insertion-Sort auf Eingabefeld A[1 . . 6]. Die Komponente, auf die der Index j zeigt“, ist rot eingefärbt. Blau eingfärbte Felder liegen im bereits ” sortierten Teilfeld A[1 . . j − 1]. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 6 Algorithmen und Datenstrukturen Beispiel: 1 2 3 4 5 6 251 245 345 456 561 63 Ausführung von Insertion-Sort auf Eingabefeld A[1 . . 6]. Die Komponente, auf die der Index j zeigt“, ist rot eingefärbt. Blau eingfärbte Felder liegen im bereits ” sortierten Teilfeld A[1 . . j − 1]. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 6 Algorithmen und Datenstrukturen Beispiel: 1 2 3 4 5 6 125 245 345 456 561 63 Ausführung von Insertion-Sort auf Eingabefeld A[1 . . 6]. Die Komponente, auf die der Index j zeigt“, ist rot eingefärbt. Blau eingfärbte Felder liegen im bereits ” sortierten Teilfeld A[1 . . j − 1]. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 7 Algorithmen und Datenstrukturen Pseudocode-Konventionen 1. Einrücken verdeutlicht die Blockstruktur. 2. Schleifenkonstrukte wie in Pascal, C, C++ oder Java. Die Zählvariable einer for -Schleife ist auch nach Schleifenende noch definiert. 3. Text von -Symbol bis Zeilenende ist ein Kommentar. 4. Variablen sind lokal wenn nicht anders vermerkt. 5. Auf Elemente eines Feldes (Arrays) wird zugegriffen durch den Namen des Feldes gefolgt vom Elementindex in eckigen Klammern. Indexbereiche werden durch . . angegeben. 6. Eine mehrfache Zuweisung wie i ← j ← e ist eine Kurzschreibweise für die Zuweisung j ← e gefolgt von der Zuweisung i ← j. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 8 Algorithmen und Datenstrukturen 7. Oft treten Objekte auf, welche Attribute besitzen. Das Attribur attr eines Objektes x wird bezeichnet mit attr [x]. 8. Objekte werden, wie in Java, als Referenzen behandelt. Sind x, y Objekte, so zeigen nach der Zuweisung y ← x beide auf dasselbe Objekt. Dies zieht kein Kopieren von Attributen nach sich. 9. Unterprogrammparameter werden als Wert ( call by value“) übergeben, ” aber als Referenz, falls es sich um Objekte handelt. 10. Logische Ausdrücke mit den Operatoren und“ sowie oder“ werden ” ” verkürzt ausgewertet, falls nach Auswertung eines Teils eines logischen Ausdrucks der Wahrheitswert des gesamten Ausdrucks bereits feststeht. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 9 Algorithmen und Datenstrukturen Korrektheit Zur Prüfung, ob ein Algorithmus das richtige Resultat liefert, werden oft Schleifeninvarianten verwendet. Für die äußere for -Schleife von I NSERTION S ORT eignet sich: Schleifeninvariante: Zu Beginn jedes Durchlaufs der äußeren for -Schleife besteht das Teilfeld A[1 . . j − 1] aus den dort ursprünglich enthaltenen Zahlen in aufsteigend sortierter Reihenfolge. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 10 Algorithmen und Datenstrukturen Für den Korrektheitsnachweis ist über die Invariante folgendes zu zeigen: Initialisierung: Die Invariante ist vor dem ersten Durchlauf erfüllt. Erhaltung: Ist die Invariante vor einem Durchlauf erfüllt, so auch danach. Terminierung: Endet die Schleife, so liefert die Invariante – oft zusammen mit dem Grund für den Schleifenabbruch – eine für den Korrektheitsnachweis hilfreiche Aussage. Man beachte die Ähnlichkeit mit dem mathematischen Prinzip der vollständigen Induktion (Induktionsanfang, Induktionsschritt). Im Unterschied hierzu wird die Invariante jedoch nur für endlich viele Durchläufe benötigt, da die Schleife in der Regel abbrechen soll. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 11 Algorithmen und Datenstrukturen Nachweis für I NSERTION -S ORT: Initialisierung: Unmittelbar vor der ersten Iteration ist j = 2; somit besteht das Teilfeld A[1 . . j − 1] aus dem ersten Element des Feldes und ist trivialerweise sortiert. Erhaltung: Strengenommen müßte man auch für die innere while Schleife eine Invariante aufstellen und beweisen. Wir halten aber informal fest, dass deren Wirken darin besteht, die Einträge A[j − 1], A[j − 2], . . . solange jeweils um eine Position nach rechts zu verschieben, bis die richtige Einfügeposition für key (dessen Wert anfangs in A[j] stand) freigeworden ist. Dort wird daraufhin der Wert von key geschrieben. Terminierung: Die äußere for -Schleife terminiert sobald j > n, was zum erstenmal bei j = n + 1 zutrifft, also für j − 1 = n. Einsetzen von j − 1 = n in die Schleifeninvariante liefert die Aussage, dass das gesamte Feld nun sortiert ist. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 12 Algorithmen und Datenstrukturen Analyse von Algorithmen Aufwand eines Algorithmus: Laufzeit, Speicherbedarf, Kommunitationsbedarf, etc. Um den Aufwand (üblicherweise die Laufzeit) beim Ausführen eines Algorithmus zu beschreiben, muss ein Berechnungsmodell (Maschinenmodell) zugrundegelegt werden. • Welche Grundoperationen stehen zur Verfügung? • Wie lange dauern diese? • Wie sehen die Daten aus? • Möglichst nahe an realen Computern, aber einfach genug, um Aussagen herleiten zu können. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 13 Algorithmen und Datenstrukturen Das Modell der Random-Access Maschine (RAM) • Anweisungen werden nacheinander, nicht gleichzeitig ausgeführt. • Um die Mühe, jeder Anweisung einen Zeitaufwand zuzuordnen, zu umgehen, legen wir fest, dass folgende, in realen Computern auftretende Operationen einen konstanten (gleichen) Zeitaufwand darstellen ◦ Arithmetik: Addition, Subtraktion, Multiplikation, Division, Rest, nächstgrößere/-kleinere ganze Zahl, Links- und Rechtsshift. ◦ Datenbewegung: Laden (load), Abspeichern (store), Kopieren (copy). ◦ Steuerung: bedingte/unbedingte Verzweigung, Unterprogrammaufruf und -rücksprung. • Speicherhierarchien werden nicht berücksichtigt. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 14 Algorithmen und Datenstrukturen Datentypen: Das RAM-Modell enthält ganze Zahlen (integer) sowie Gleitpunktzahlen (floating point). Dabei ist anzumerken: • Wir lassen die Genauigkeit der Zahldarstellung außer acht, diese kann jedoch in gewissen numerischen Anwendungen von grösserer Bedeutung sein. • Die Wortlänge ist begrenzt: treten Zahlen der Größenordnung n auf, so nehmen wir an, diese würden durch c log2 n Bits dargestellt, wobei ◦ c ≥ 1, d.h. jedes Wort kann den Wert n aufnehmen (speichern) und wir können n Größen indizieren; ◦ c ist eine Konstante, d.h. kann nicht als beliebig groß angenommen werden. (Ansonsten beliebig große Datenmengen in einem Wort speicherbar, in einer Operation bearbeitbar: unrealistisch) 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 15 Algorithmen und Datenstrukturen Wie wird die Laufzeit eines Algorithmus analysiert ? Laufzeit hängt von den Eingabedaten ab: • 1000 Zahlen sortieren dauert länger als 3 Zahlen sortieren. • Selbst bei zwei Sätzen von Eingabedaten gleicher Länge ist die Laufzeit von I NSERTION -S ORT für bereits sortierte Eingabedaten kürzer als wenn diese umgekehrt sortiert sind. Größe der Eingabe: hängt auch von der Aufgabe ab. • Typisch: Anzahl Objekte in der Eingabe (etwa Länge eines zu sortierenden Feldes). • Kann auch anders sein, etwa bei der Multiplikation zweier ganzer Zahlen die Bitlänge des Ergebnisses. • Kann von mehreren Größen abhängen, etwa bei Graphenalgorithmen Anzahl Knoten und Kanten des Eingabegraphen. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 16 Algorithmen und Datenstrukturen Laufzeit: bei gegebenen Eingabedaten die Anzahl auszuführender Grundoperationen (Schritte). • Definition der Schritte sollte maschinenunabhängig sein. • Jede Zeile Pseudocode erfordert konstante Zeit. • Zeilen können unterschiedlichen Zeitaufwand erfordern, aber jede Abarbeitung der i-ten Zeile erfordert stets denselben Aufwand ci . • Zugrundeliegende Annahme: jede Zeile enthält ausschließlich Grundoperationen. ◦ Enthält eine Zeile einen Unterprogrammaufruf, so ist der Aufwand des Aufrufs zwar konstant, aber nicht notwendig die Ausführung des Unterprogramms. ◦ Enthält die Zeile andere als Grundoperationen (z.B. sortiere Punkte ” nach aufsteigender x-Koordinate“), so ist deren Laufzeit evtl. nicht konstant. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 17 Algorithmen und Datenstrukturen Analyse von Insertion-Sort • ci bezeichne den Zeitaufwand für Zeile i. • Für j = 2, 3, . . . , n bezeichne tj die Anzahl, wie oft beim Durchlauf mit Index j die Abbruchbedingung der while -Schleife geprüft wird. • Beachte: beim regulären Abbruch einer for - oder while -Schleife wird die Abbruchbedingung einmal öfter als der Rumpf der Schleife ausgeführt. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 18 Algorithmen und Datenstrukturen Aufwand Anzahl I NSERTION -S ORT(A) 1 for j ← 2 to length[A] 2 do key ← A[j] 3 Füge A[j] ein in die sortierte Folge A[1 . . j − 1]. 4 i←j−1 5 while i > 0 and A[i] > key 6 do A[i + 1] ← A[i] 7 i←i−1 8 A[i + 1] ← key 1.1 Sortieren durch Einfügen (Insertion-Sort) c1 c2 n n−1 c4 c5 c6 c7 c8 n−1 Pn tj Pj=2 n (tj − 1) Pj=2 n j=2 (tj − 1) n−1 TU Bergakademie Freiberg, WS 2005/06 19 Algorithmen und Datenstrukturen Die Laufzeit ergibt sich als X (Aufwand der Anweisung) · (Anzahl deren Ausführungen). alle Anweisungen Für die Laufzeit T (n) von I NSERTION -S ORT erhalten wir T (n) = c1 n + c2 (n − 1) + c4 (n − 1) + c5 n X j=2 + c7 n X tj + c6 n X (tj − 1) j=2 (tj − 1) + c8 (n − 1). j=2 Die Laufzeit hängt damit neben n auch von den Größen tj ab, welche ihrerseits von den Eingabedaten abhängen. Wir betrachten zwei Spezialfälle. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 20 Algorithmen und Datenstrukturen Günstigster Fall (best case): Eingabefeld ist bereits (aufsteigend) sortiert. • In jedem Durchlauf der for -Schleife ist die Abbruchbedingung der while -Schleife stets beim ersten Mal erfüllt (es gilt stets A[i] ≤ key für i = j − 1). Damit gilt tj = 1 für alle j. • Für die Laufzeit gilt somit T (n) = c1 n + c2 (n − 1) + c4 (n − 1) + c5 (n − 1) + c8 (n − 1) = (c1 + c2 + c4 + c5 + c8 )n − (c2 + c4 + c5 + c8 ). • Es gilt also T (n) = an+b mit Konstanten a, b (welche von Ausführungszeiten von Grundanweisungen abhängen). Damit ist T (n) eine lineare Funktion von n. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 21 Algorithmen und Datenstrukturen Der ungünstigste Fall (worst case): Eingabefeld ist absteigend sortiert. • In der while -Bedingung ist stets A[j] > key. • key muss mit allen links von Position j stehenden Einträgen verglichen werden, d.h. es sind jedes Mal j − 1 Vergleiche erforderlich. • Die while -Schleife bricht also stets erst bei i = 0 ab, also gilt tj = j. • Somit folgt n X n X n(n + 1) tj = j= − 1, 2 j=2 j=2 n X j=2 1.1 Sortieren durch Einfügen (Insertion-Sort) (tj − 1) = n X j=2 (j − 1) = n−1 X k=1 (n − 1)n k= . 2 TU Bergakademie Freiberg, WS 2005/06 22 Algorithmen und Datenstrukturen • Somit gilt n(n + 1) T (n) = c1 n + c2 (n − 1) + c4 (n − 1) + c5 −1 2 n(n − 1) n(n − 1) + c6 + c7 + c8 (n − 1) 2 2 c5 + c6 + c7 2 c5 − c6 − c7 = n + c1 + c2 + c4 + + c8 n 2 2 − (c2 + c4 + c5 + c8 ). • In diesem Fall gilt T (n) = an2 + bn + c mit Konstanten a, b, c, d.h. T (n) ist eine quadratische Funktion von n. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 23 Algorithmen und Datenstrukturen Analyse im ungünstigsten und mittleren Fall Es ist sinnvoll, zunächst die Laufzeit im ungünstigsten Fall, d.h. die längste Laufzeit bei allen möglichen Eingaben der Länge n, zu bestimmen. Gründe: • Die worst-case-Laufzeit liefert eine obere Schranke für die Laufzeit für beliebige Eingaben. • Für einige Algorithmen tritt der ungünstigste Fall hinreichend oft auf. (Bei Suchalgorithmen beispielsweise immer bei Nichtvorhandensein des gesuchten Objektes) • Das Verhalten im mittleren Fall ist oft nicht viel besser als im ungünstigsten Fall. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 24 Algorithmen und Datenstrukturen Beispiel: Angenommen die Eingabe für I NSERTION -S ORT bestehe aus n zufällig gewählten Zahlen. Im Mittel ist der in A[j] enthaltene Schlüssel kleiner als die Hälfte der Zahlen in A[1 . . j − 1], und größer als die andere Hälfte. ⇒ Im Mittel muss die while -Schleife das bereits sortierte Teilfeld A[1 . . j−1] zur Hälfte durchsuchen bis die Einfügestelle für key gefunden ist. ⇒ tj = j/2. Obwohl damit die mittlere Laufzeit halb so groß ist wie die worst-caseLaufzeit, ist diese immer noch eine quadratische Funktion von n. Allgemein: Aussagen über mittlere Laufzeit erfordern stochastische Methoden sowie Annahmen über die Wahrscheinlichkeiten der möglichen Eingaben. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 25 Algorithmen und Datenstrukturen Wachstumsordnung Oft ist das Laufzeitverhalten eines Algorithmus hinreichend genau beschrieben durch den führenden Term der Laufzeitformel, d.h. man kann die Terme niederer Ordnung sowie die Konstante im führenden Term ignorieren. Beispiel: I NSERTION -S ORT mit worst-case-Laufzeit T (n) = an2 + bn + c. Weglassen der Terme niederer Ordnung −→ an2 Ignorieren der Konstanten −→ n2 Natürlich gibt dieser vereinfachte Ausdruck nicht mehr die Laufzeit an, sondern lediglich deren Wachstumsordnung, d.h. T (n) wächst wie n2 . Man sagt nun, die Laufzeit sei Θ(n2 ), um diesen Sachverhalt auszudrücken. Ein Algorithmus wird effizienter als ein anderer eingestuft, falls seine worst-case-Laufzeit eine kleinere Wachstumsordnung aufweist. 1.1 Sortieren durch Einfügen (Insertion-Sort) TU Bergakademie Freiberg, WS 2005/06 26 Algorithmen und Datenstrukturen 1.2 Sortieren durch Mischen (Merge-Sort) Entwurfsprinzip bei I NSERTION -S ORT: Inkrementelles Sortieren, d.h. nach Sortieren des Teilfeldes A[1 . . j − 1] wird A[j] so eingefügt, dass A[1 . . j] sortiert ist. Weiteres Entwurfsprinzip: Divide and conquer ( teile und herrsche“): ” 1. Zerlege das Problem in Teilprobleme (typischerweise zwei ungefähr gleich große) 2. Löse die Teilprobleme (rekursiv) 3. Kombiniere die Teillösungen zur Gesamtlösung 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 27 Algorithmen und Datenstrukturen M ERGE -S ORT ist ein auf der Divide-and-conquer-Strategie basierendes Sortierverfahren mit einer Worst-case Laufzeit von niedrigerer Ordnung als die von I NSERTION -S ORT. Die Teilprobleme bestehen im Sortieren von Teilfeldern A[p . . r], wobei das Ausgangsproblem durch p = 1 und r = n gekennzeichnet ist. Sortieren von A[p . . r]: 1. Zerlege A[p . . r] in zwei Teilfelder A[p . . q] und A[q + 1, . . r], wobei q in der Mitte zwischen p und r liegt. 2. Sortiere (rekursiv) beide Teilfelder. Die Rekursion endet bei Teilfeldern der Länge eins. 3. Füge die sortierten Teilfelder zu einem sortierten Gesamtfeld zusammen. Dieser Schritt wird durch die unten definierte Prozedur M ER GE (A, p, q, r) geleistet. 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 28 Algorithmen und Datenstrukturen Pseudocode: M ERGE -S ORT(A, p, r) 1 if p < r 2 then q ← b(p + r)/2c 3 M ERGE -S ORT(A, p, q) 4 M ERGE -S ORT(A, q + 1, r) 5 M ERGE(A, p, q, r) Prüfe ob Rekursion zuende. Zerlege. Sortiere linkes Teilfeld. Sortiere rechtes Teilfeld. Füge Teilfelder zusammen. Erster Aufruf: M ERGE -S ORT(A, 1, n). 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 29 Algorithmen und Datenstrukturen Beispiel: Zerlegephase für n = 8 1 2 3 4 5 6 7 8 5 2 4 7 1 3 2 6 5 2 4 7 1 3 2 6 5 2 4 7 1 3 2 6 5 2 4 7 1 3 2 6 1 2 3 4 5 6 7 8 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 30 Algorithmen und Datenstrukturen Beispiel: Zerlegephase für n = 11 1 2 3 4 5 6 7 8 9 10 11 4 7 2 6 1 4 7 3 5 2 6 4 7 2 6 1 4 7 3 5 2 6 4 7 2 6 1 4 7 3 5 2 6 4 7 2 6 1 4 7 3 5 2 6 4 7 2 6 1 4 7 3 5 2 6 1 2 3 4 5 6 7 8 9 10 11 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 31 Algorithmen und Datenstrukturen Zusammenfügen Eingabe: Feld A, Indizes p, q, r mit • p≤q<r • Beide Teilfelder A[p . . q] und A[q + 1 . . r] sind sortiert. Insbesondere sind beide nicht leer. Ausgabe: Beide Teilfelder vereint in einem sortierten Feld A[p . . r]. Wir konstruieren hierfür einen Algorithmus mit Laufzeit Θ(n), n = r−p+1 = # zusammengefügter Elemente. Bemerkung: Bisher bezeichnete n die Größe des Ausgangsproblems, hier bezeichnet es die des Teilproblems. Dies ist üblich bei der Analyse rekursiver Algorithmen. 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 32 Algorithmen und Datenstrukturen Zusammenfügen in linearer Zeit (Grundidee) Betrachte als Analogie zwei Spielkartenstapel: • Beide Stapel sind sortiert und liegen offen auf dem Tisch, mit der niedrigstwertigen Karte obenauf. • Wir fügen diese zu einem sortierten verdeckten Stapel zusammen. • Grundoperation: ◦ Wähle die niedrigere der beiden obenliegenden Karten. ◦ Entferne diese aus ihrem Stapel und lege sie verdeckt auf den Ausgabestapel. • Wiederhole die Grundoperation bis einer der beiden Stapel abgearbeitet ist. • Setzte den verbleibenden Stapel verdeckt auf den Ausgabestapel. 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 33 Algorithmen und Datenstrukturen Laufzeit: • Jede Grundoperation erfordert konstanten Aufwand, da hierbei stets zwei Karten verglichen werden. • Die Grundoperation muss höchstens n Mal ausgeführt werden, da nur soviele Karten in beiden Ausgangsstapeln enthalten sind. • Insgesamt erfordert das Mischen somit Θ(n) Laufzeit. 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 34 Algorithmen und Datenstrukturen Durch folgenden Trick kann man sich die Prüfung auf leeren Stapel ersparen: • Beide Ausgangsstapel erhalten als unterste Karte eine Sonderkarte mit Wertigkeit ∞. Diese ist höher als die Wertigkeit jeder anderen Karte bis auf die zweite Sonderkarte. • Wir wissen im Voraus, dass genau n = r − p + 1 gewöhnliche Karten zu verarbeiten sind, danach kann der Algorithmus enden. (Die Sonderkarten werden nie in den Ausgabestapel einsortiert.) 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 Algorithmen und Datenstrukturen 35 M ERGE(A, p, q, r) n1 ← q − p + 1 n2 ← r − q Erzeuge Hilfsfelder L[1 . . n1 + 1] und R[1 . . n2 + 1] for i ← 1 to n1 do L[i] ← A[p + i − 1] for j ← 1 to n2 do R[j] ← A[q + j] L[n1 + 1] ← ∞, R[n2 + 1] ← ∞ i ← 1, j ← 1 for k ← p to r do if L[i] ≤ R[j] then A[k] ← L[i], i ← i + 1 else A[k] ← R[j], j ← j + 1 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 36 Algorithmen und Datenstrukturen Analyse von Divide-and-conquer Algorithmen Rekursionsgleichung für T (n) = Laufzeit für Problem der Größe n • Ist die Problemgröße klein genug (n ≤ c) so liegt ein Basisfall vor, dessen Lösung konstante Zeit erfordert: Θ(1). • Andernfalls zerlegen wir in a Teilprobleme, jedes 1/b Mal so groß wie das Ausgangsproblem (a = b = 2 für M ERGE -S ORT). • Erforderliche Zeit für Zerlegen eines Problems der Größe n sei D(n). • a zu lösende Teilprobleme der Größe n/b, jedes Teilproblem erfordert Laufzeit T (n/b) ⇒ insgesamte Laufzeit aT (n/b) zur Lösung der Teilprobleme. • Sei C(n) der Aufwand zum Zusammenfügen der Teillösungen eines Ausgangsproblems der Größe n. 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 37 Algorithmen und Datenstrukturen Wir erhalten die Rekursionsgleichung ( Θ(1) T (n) = aT (n/b) + D(n) + C(n) 1.2 Sortieren durch Mischen (Merge-Sort) falls n ≤ c, sonst. TU Bergakademie Freiberg, WS 2005/06 38 Algorithmen und Datenstrukturen Analyse von Merge-Sort Zur Vereinfachung sei n eine Zweierpotenz, d.h. n = 2k für ein k ∈ N0 . Jeder Zerlegungsschritt erzeugt Teilprobleme von Größe genau n/2. Der Basisfall tritt ein für n = 1. Laufzeit der Merge-Sort Phasen für n ≥ 2: Zerlegen: Berechnung von q als Mittelwert von p und r, d.h. D(n) = Θ(1) Teillösungen: Rekursive Lösung zweier Teilproblemen der Größe n/2: 2T (n/2) Zusammenfügen: M ERGE angewandt auf Feld von Gesamtlänge n erfordert Laufzeit Θ(n), also C(n) = Θ(n). 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06 39 Algorithmen und Datenstrukturen Schließlich gilt D(n) + C(n) = Θ(1) + Θ(n) = Θ(n), und wir erhalten T (n) = ( Θ(1) 2T (n/2) + Θ(n) falls n = 1, falls n > 1. Lösung der Rekursionsgleichung: Man kann zeigen (siehe Kapitel 3) dass für die Lösung obiger Rekursiongleichung gilt T (n) = Θ(n log n). Da n log n langsamer wächst als n2 besitzt M ERGE -S ORT asymptotisch eine geringere Laufzeit als I NSERTION -S ORT. Dies wirkt sich u.U. erst für hinreichend große n aus. 1.2 Sortieren durch Mischen (Merge-Sort) TU Bergakademie Freiberg, WS 2005/06