Sortieren in Arrays. Kapitel 10

Größe: px
Ab Seite anzeigen:

Download "Sortieren in Arrays. Kapitel 10"

Transkript

1

2 Kapitel 10 Sortieren in Arrays Sortieralgorithmen gehören zu den am häufigsten angewendeten Algorithmen in der Datenverarbeitung. Man hatte daher bereits früh ein großes Interesse an der Entwicklung möglichst effizienter Sortieralgorithmen. Zu diesem Thema gibt es umfangreiche Literatur, nahezu jedes Buch über Algorithmen und Datenstrukturen beschäftigt sich mit Sortieralgorithmen, da sie besonders geeignet sind, Anfängern Programmiermethodik, Entwurf von Algorithmen und Aufwandsanalyse zu lehren. Wir erläutern die Sortieralgorithmen vor folgendem Hintergrund. Gegeben ist ein Datentyp Item. public class Item { int key; // data components and methods Objekte dieses Typs sind Karteikarten, z. B. aus einer Studentenkartei. Jede Karteikarte enthält neben den Daten (data components) einen Schlüssel (key) vom Typ int, z. B. die Matrikelnummer, nach denen sortiert oder gesucht werden kann. Die gesamte Kartei wird durch ein Array vec mit Grundtyp Item dargestellt. Wir reden daher im weiteren auch von Komponenten oder Elementen statt Karteikarten. Die Wahl von int als Schlüsseltyp ist willkürlich. Hier kann jeder andere Typ verwendet werden, für den eine vollständige Ordnungsrelation definiert ist, also zwischen je zwei Werten a,b genau eine der Relationen a < b, a = b, a > b gilt. Dies können z. B. auch Strings mit der lexikographischen Ordnung sein (Meier < Mueller), nur müsste dann der eingebaute Vergleich < von ganzen Zahlen durch eine selbstdefinierte Funktion zum Vergleich von Strings ersetzt werden. 1 1 Dies kann mit dem Interface Comparable (vgl. Abschnitt 7.3.7) realisiert werden. Die Klasse Item muss dazu die Methode public int compareto(object o) implementieren. Dabei ist das Item x kleiner als oder gleich dem Item y wenn x.compareto((object)y) <= 0 gilt. Alle Sortieralgorithmen nutzen dann die Abfrage x.compareto((object)y) <= 0 für den Vergleich von x und y. Version vom 30. Dezember

3 50 KAPITEL 10. SORTIEREN IN ARRAYS 10.1 Direkte Methoden Direkt bedeutet: Sortieren der Komponenten am Ort. Ein typisches Beispiel dafür ist Bubblesort Sortieren durch Austauschen: Bubblesort Bubblesort durchläuft das Array mehrmals von hinten nach vorn und lässt durch paarweise Vergleiche das kleinste Element der restlichen Menge zum linken Ende des Arrays wandern. Stellt man sich das Array senkrecht angeordnet vor, und die Elemente als Blasen, so steigt bei jedem Durchlauf durch das Array eine Blase auf die ihrem Gewicht (Schlüsselwert) entsprechende Höhe auf (vgl. Abbildung 10.1) j vec[j].key i= Abbildung 10.1: Phasen bei Bubblesort. Informell lässt sich Bubblesort wie folgt beschreiben: 1. Gegeben ist vec[] mit n Komponenten.. Das Array vec wird n 1 mal von hinten nach vorn durchlaufen. Ein Durchlauf heißt Phase. 3. Phase i läuft von Komponente j = n 1 bis j = i und vergleicht jeweils vec[j].key mit vec[j-1].key. Ist vec[j-1].key > vec[j].key so werden vec[j-1] und vec[j] getauscht. Die Korrektheit des Algorithmus ergibt sich direkt aus folgender Schleifeninvarianten, die nach jeder Phase gilt: Am Ende der Phase i ist vec[i-1].key der i-kleinste Schlüssel in vec und es gilt: vec[0].key vec[1].key... vec[i-1].key vec[j].key für j = i,i + 1,...,n 1. (10.1) Dies ist klar für die 1. Phase. Nimmt man die Richtigkeit für Phase i an (Induktionsvoraussetzung), so findet Phase i + 1 das kleinste Element in vec[i]...vec[n-1] und bringt es durch ggf. fortgesetzte Austauschoperationen an die Position i. Also gilt die Invariante auch nach Phase i (Induktionsschluss). Für i = n 1 folgt sofort die Korrektheit des Algorithmus.

4 10.1. DIREKTE METHODEN 51 Dies resultiert in die folgende Java Methode. /** * Sorts with bubblesort algorithm vec the array to be sorted NullPointerException if <code>vec</code> * is not initialized */ public static void bubblesort(item[] vec) throws NullPointerException { if (vec == null) throw new NullPointerException(); int n = vec.length; Item temp; int bottom; // bottom for each pass for (bottom = 1; bottom < n; bottom++) { for (int i = n-1; i >= bottom; i--) { if (vec[i-1].key > vec[i].key) { temp = vec[i-1]; vec[i-1] = vec[i]; vec[i] = temp; Wir berechnen nun den Worst Case Aufwand von Bubblesort nach der Anzahl der Vergleiche. Dazu betrachten wir die Vergleiche pro Phase. Sei n die Anzahl der Komponenten des Arrays. Phase 1 : n 1 Vergleiche Phase : n Vergleiche... Phase i : n i Vergleiche... Phase n 1 : 1 Vergleich Also gilt für die Anzahl C(n) der Vergleiche bei n Komponenten n 1 C(n) = (n ) + (n 1) = i=1 i = n(n 1). Folglich ist C(n) O(n ). Da die Vergleiche unabhängig von der Eingabe durchgeführt werden (auch bei einem bereits sortierten Array) gilt: C(n) = n(n 1) n 3 für n 3, also C(n) Ω(n ) und damit C(n) Θ(n ).

5 5 KAPITEL 10. SORTIEREN IN ARRAYS Offensichtlich kann dieser Algorithmus verbessert werden, wenn man sich merkt, ob in einer Phase überhaupt ein Austausch stattgefunden hat. Findet kein Austausch statt, so ist das Array sortiert und man kann abbrechen. Eine weitere Verbesserung besteht darin, sich in einer Phase die Position (Index) k des letzten Austausches zu merken. In den darauf folgenden Phasen müssen vec[0]...vec[k] nicht mehr überprüft werden. Schließlich kann man noch die Phasen abwechselnd von hinten nach vorn und von vorn nach hinten laufen lassen (Shakersort), um Asymmetrie zwischen leichten Elementen (gehen gleich ganz nach oben) und schweren Elementen (sinken jeweils nur um eine Position ab) zu durchbrechen. Diese Verbesserungen bewirken aber nur eine Verringerung der mittleren Anzahl der Vergleiche. Für den Worst Case lassen sich stets (Übung) Beispiele finden, die C(n) = n(n 1) Vergleiche benötigen. Es gilt also: Satz 10.1 Bubblesort erfordert Θ(n ) Vergleiche im Worst Case. Neben der Anzahl C(n) der Vergleiche ist für die Laufzeit auch die Anzahl A(n) der Zuweisungen (Assignments) von Arraykomponenten von großer Bedeutung, da sie außer den Schlüsseln noch weitere (ggf. große) Datenmengen enthalten. Offenbar kann jeder Vergleich einen Austausch und damit 3 Zuweisungen verursachen. Es gilt also A(n) 3 C(n). Beispiele zeigen, dass A(n) = 3 C(n) vorkommt. Also folgt: Satz 10. Bubblesort erfordert Θ(n ) Zuweisungen im Worst Case Sortieren durch direktes Auswählen: Selection Sort Wir geben zunächst eine informelle Beschreibung: 1. Gegeben ist vec[] mit n Komponenten.. Das Array vec wird n 1 mal von vorn nach hinten durchlaufen. Ein Durchlauf heißt Phase (pass). 3. Phase bottom sucht den Index minindx einer Komponente mit kleinstem Schlüsselwert im Bereich vec[bottom], vec[bottom+1],...,vec[n-1], mittels sequentieller Suche, und tauscht diese Komponente an die Stelle bottom. Es werden also vec[bottom] und vec[minindx] vertauscht. Die Korrektheit basiert hier auf derselben Invarianten wie bei Bubblesort. Es folgt eine Java Methode:

6 10.1. DIREKTE METHODEN 53 /** * Sorts with selectionsort algorithm vec the array to be sorted NullPointerException if <code>vec</code> * is not initialized */ public static void selectionsort(item vec[]) throws NullPointerException { if (vec == null) throw new NullPointerException(); int minindx; int bottom; int i; Item temp; int n = vec.length; // Index of smallest key in each pass // bottom for each pass for (bottom = 0; bottom < n-1; bottom++) { // INVARIANT (prior to test): // All vec[bottom+1..n-1] are >= vec[bottom] // && vec[0..bottom] are in ascending order // && bottom >= 0 minindx = bottom; for (i = bottom+1; i < n; i++) { // INVARIANT (prior to test): // vec[minindx] <= all // vec[0..i-1] // && i >= bottom+1 if (vec[i].key < vec[minindx].key) { minindx = i; temp = vec[bottom]; vec[bottom] = vec[minindx]; vec[minindx] = temp; Für das Beispiel aus Abbildung 10.1 ergeben sich die in Abbildung 10. dargestellten Zustände nach den einzelnen Phasen Für die Anzahl C(n) der Vergleiche ergibt sich analog zu Bubblesort: n 1 C(n) = i=1 (n i) = n(n 1),

7 54 KAPITEL 10. SORTIEREN IN ARRAYS Phase Array vec Input Abbildung 10.: Phasen bei Straight Selection Sort. da die sequentielle Suche in Phase i (Bestimmung des Minimum in n i + 1 Komponenten) gerade n i Vergleiche erfordert. Die Anzahl A(n) der Zuweisungen von Arraykomponenten ist jedoch deutlich geringer, da pro Phase maximal ein Austausch erfolgt. Also gilt A(n) 3(n 1) = O(n). Beispiele zeigen wieder, dass C(n) Θ(n ) und A(n) Θ(n) gilt Sortieren durch direktes Einfügen: Insertion Sort Diese Methode wird oft beim Kartenspiel genutzt. Die Arraykomponenten (Karten) werden gedanklich in eine Zielsequenz vec[0]...vec[i-1] (die Karten, die man bereits in der Hand hat) und die Quellsequenz vec[i]...vec[n-1] (die Karten für die eigene Hand, die noch verdeckt auf dem Tisch liegen) aufgeteilt. Dann lässt sich der Algorithmus folgendermaßen beschreiben: 1. Gegeben ist vec[] mit n Komponenten. Anfangs besteht die Zielsequenz aus vec[0] und die Quellsequenz aus vec[1]...vec[n-1].. Es finden n 1 Phasen i = 1,...,n 1 statt. 3. In Phase i wird die nächste Karte vec[i] der Quellsequenz genommen und an der richtigen Stelle (bzgl. vec[i].key) in die Zielsequenz vec[0]...vec[i-1] eingefügt. Die Korrektheit dieses Algorithmus folgt aus der folgenden Invariante: Nach jeder Phase i gilt vec[0].key vec[1].key... vec[i].key. (10.) Im Standardbeispiel ergeben sich die in Abbildung 10.3 dargestellten Zustände nach jeder Phase:

8 10.1. DIREKTE METHODEN 55 Phase Array vec Input Abbildung 10.3: Phasen bei Insertion Sort. Die Anzahl der Vergleiche hängt davon ab, wie das Einfügen in die Zielsequenz durchgeführt wird. Bei sequentieller Suche der Stelle (von links nach rechts) ergeben sich im Worst Case folgende Zahlen: Phase 1 : 1 Vergleich Phase : Vergleiche... Phase n 1 : n 1 Vergleiche In diesem Fall ist wiederum C(n) = n(n 1) O(n ). Da die Zielsequenz bereits aufsteigend sortiert ist, lässt sich statt der sequentiellen Suche die binäre Suche verwenden. Phase i erfordert dann (Zieldatei enthält i Elemente) gemäß Satz 6.1 höchstens logi + 1 Vergleiche. Also gilt dann: C(n) n 1 i=1 n 1 i=1 ( logi + 1) (log(n 1) + 1) = (n 1)(log(n 1) + 1) = (n 1)log(n 1) + (n 1) = O(nlogn) Bezüglich der Zahl A(n) der Zuweisungen von Arraykomponenten ist in beiden Varianten (sequentielle oder binäre Suche) eine Verschiebung der Komponenten der Quelldatei rechts von der Einfügestelle k um jeweils eine Stelle erforderlich, im schlimmsten Fall (k = 0) also i Verschiebungen in Phase i. Dies lässt sich mit i + 1 Zuweisungen realisieren: temp = vec[i]; for (j = i-1; j >= 0; j++) vec[j+1] = vec[j]; vec[0] = temp; Also ist A(n) n 1 i=1 (i + 1) = n i= i = ( = n(n+1) 1 O(n ). n i=1 i) 1

9 56 KAPITEL 10. SORTIEREN IN ARRAYS Das Beispiel des absteigend sortierten Arrays zeigt, dass dieser Fall auch eintritt, also A(n) Ω(n ) gilt. Straight Insertion (mit binärer Suche) ist also bezüglich der Anzahl der Vergleiche sehr gut (O(n log n)), aber bezüglich der Anzahl der Zuweisungen schlecht (Ω(n )). Die hier vorgestellten direkten Methoden sind mit ihrer Worst Case Laufzeit von Θ(n ) als sehr aufwendig einzustufen. Wir werden im Rest des Kapitels drei intelligentere Sortiermethoden kennen lernen, die im Mittel, und teilweise auch im Worst Case, mit O(n log n) Vergleichen und Zuweisungen auskommen. 10. Mergesort Mergesort teilt das zu sortierende Array in zwei gleichgroße Teilfolgen (Unterschied höchstens eine Komponente), sortiert diese (durch rekursive Anwendung von Mergesort auf die beiden Teile) und mischt die dann sortierten Teile zusammen Mischen sortierter Arrays Wir betrachten daher zunächst das Mischen von zwei bereits sortierten Arrays. Seien dazu vec1[] und vec[] bereits sortierte Arrays der Länge m bzw. n mit Komponenten vom Typ Item. Diese sind in das Array vec[] der Länge m + n zu verschmelzen. Dazu durchlaufen wir vec1 und vec von links nach rechts mit zwei Indexzeigern i und j wie folgt: 1. Initialisierung: i = 0; j = 0; k= 0;. Wiederhole Schritt 3 bis i = m oder j = n. 3. Falls vec1[i].key < vec[j].key, so kopiere vec1[i] an die Position k von vec und erhöhe i und k um 1. Andernfalls kopiere vec[j] an die Position k von vec und erhöhe j und k um Ist i = m und j < n, so übertrage die restlichen Komponenten von vec nach vec. 5. Ist j = n und i < m, so übertrage die restlichen Komponenten von vec1 nach vec. Bei jedem Wiedereintritt in die Schleife 3 gilt die Invariante vec[0].key... vec[k-1].key vec[k-1].key vec1[i].key... vec1[m-1].key vec[k-1].key vec[j].key... vec[n-1].key (10.3) Hieraus folgt sofort, dass vec am Ende aufsteigend sortiert ist. Als Beispiel betrachten wir die Arrays:

10 10.. MERGESORT 57 vec1: vec: Die dazugehörige Folge der Werte von i,j,k und vec bei jedem Wiedereintritt in die Schleife 3 ist in Abbildung 10.4 angegeben. Am Ende dieser Schleife ist i = 4 und Schritt 4 des Algorithmus wird ausgeführt, d. h. der Rest von vec, also die 7, wird nach vec übertragen. i j k vec Abbildung 10.4: Phasen bei Merge. Sei C(m, n) die maximale Anzahl von Schlüsselvergleichen und A(m, n) die maximale Anzahl von Zuweisungen von Komponenten beim Mischen. Vergleiche treten nur in der Schleife 3 auf, und zwar genau einer pro Durchlauf. Da die Schleife maximal m + n 1 mal durchlaufen wird, gilt C(m,n) m + n 1. Zuweisungen treten genau n+m mal auf, da jede Komponente von vec einen Wert bekommt. Also ist A(m,n) = m + n. Wir geben nun eine Java Methode für dieses Verfahren an, und zwar in der (später benötigten) Version, dass zwei benachbarte, bereits sortierte Teilbereiche eines Arrays vec gemischt werden und dann in demselben Bereich von vec aufsteigend sortiert gemischt stehen. Wir verlangen also folgendes Input/Output Verhalten: Input: vec left middle right mit den sortierten Bereichen vec[left]...vec[middle] und vec[middle+1]...vec[right]. Output: vec left right mit dem aufsteigend sortierten Bereich vec[left]...vec[right]. Dazu werden zunächst die beiden sortierten Bereiche auf lokale Arrays vec1 und vec kopiert, die dann in den entsprechenden Bereich von vec zurückgemischt werden.

11 58 KAPITEL 10. SORTIEREN IN ARRAYS Programm 10.1 merge /** * merges two sorted adjacent ranges of an array vec the array in which this happens left start of the first range middle end of the first range right end of the second range */ private static void merge(item[] vec, int left, int middle, int right) { int i, j; int m = middle - left + 1; // length of first array region int n = right - middle; // length of second array region // make copies of array regions to be merged // (only the references to the items) Item[] copy1 = new Item[m]; Item[] copy = new Item[n]; for (i = 0; i < m; i++) copy1[i] = vec[left + i]; for (j = 0; j < n; j++) copy[j] = vec[middle j]; i = 0; j = 0; // merge copy1 and copy into vec[left...right] while (i < m && j < n) { if (copy1[i].key < copy[j].key) { vec[left+i+j] = copy1[i]; i++; else { vec[left+i+j] = copy[j]; j++; //endif //endwhile if (j == n) { // second array region is completely handled, // so copy rest of first region while (i < m) { vec[left+i+j] = copy1[i]; i++; // if (i == m) do nothing, // rest of second region is already in place

12 10.. MERGESORT Sortieren durch rekursives Mischen: Mergesort Mit dieser Methode merge() ergibt sich dann sehr einfach folgende rekursive Variante von Mergesort. Programm 10. mergesort /** * Sorts with mergesort algorithm vec the array to be sorted NullPointerException if <code>vec</code> * is not initialized */ public static void mergesort(item vec[]) throws NullPointerException { if (vec == null) throw new NullPointerException(); mergesort(vec, 0, vec.length - 1); /** * sorts array by mergesort in a certain range <code>vec</code> the array in which this happens <code>first</code> start of the range <code>last</code> end of the range */ private static void mergesort(item[] vec, int first, int last) { if (first == last) return; // devide vec into equal parts int middle = (first + last) / ; mergesort(vec, first, middle); // sort the first part mergesort(vec, middle+1, last); // sort the second part merge(vec, first, middle, last); // merge the sorted parts Die public Methode mergesort(item[]) bekommt nur das Array übergeben und ruft die private Methode mergesort(item[], int, int) in den Grenzen 0 und vec.length-1 des Arrays vec auf. Die Korrektheit von mergesort(item[], int, int) ergibt sich sofort durch vollständige Induktion nach der Anzahl n = last - first + 1 der zu sortierenden Komponenten. Ist n = 1, also last=first (Induktionsanfang), so wird im Rumpf von mergesort() nichts gemacht und das Array vec ist nach Abarbeitung von mergesort() trivialerweise im Bereich first...last sortiert. Ist n > 1, so sind first...middle und middle+1...last Bereiche mit weniger als n Elementen, die also nach Induktionsvoraussetzung durch die Aufrufe mergesort(vec, first, middle) und

13 60 KAPITEL 10. SORTIEREN IN ARRAYS mergesort(vec, middle+1, last) korrekt sortiert werden. Die Korrektheit von merge() ergibt dann die Korrektheit von mergesort. Für das Standardbeispiel a ergibt der Aufruf mergesort(a,0,7) dann den in Abbildung 10.5 dargestellten Ablauf. Dabei beschreiben die Einrücktiefe die Aufrufhierarchie (Rekursionsbaum), und die Kästen die bereits sortierten Teile des Arrays. mergesort(a,0,7) mergesort(a,0,3) mergesort(a,0,1) mergesort(a,0,0) mergesort(a,1,1) merge(a,0,0,1) mergesort(a,,3) mergesort(a,,) mergesort(a,3,3) merge(a,,,3) merge(a,0,1,3) mergesort(a,4,7) mergesort(a,4,5) mergesort(a,4,4) mergesort(a,5,5) merge(a,4,4,5) mergesort(a,6,7) mergesort(a,6,6) mergesort(a,7,7) merge(a,6,6,7) merge(a,4,5,7) merge(a,0,3,7) Abbildung 10.5: Die Rekursion bei mergesort() Die Analyse von Mergesort Wir ermitteln nun den Worst Case Aufwand C(n) für die Anzahl der Vergleiche und A(n) für die Anzahl der Zuweisungen von mergesort() beim Sortieren eines Arrays mit n Komponenten.

14 10.. MERGESORT 61 Aus dem rekursiven Aufbau des Algorithmus ergeben sich sofort die folgenden Rekursionsgleichungen für C(n). C() = 1 C(n) = C(n) +C(n,n) für n > 1 In Worten: Das Sortieren eines -elementigen Arrays erfordert einen Vergleich. Das Sortieren eines Arrays der Länge n erfordert den Aufwand für das Sortieren von Arrays der Länge n (rekursive Aufrufe von mergesort() für die beiden Teile), also C(n), plus den Aufwand C(n,n) für das Mischen (Aufruf von merge()). Da C(n,n) = n 1, ist also C() = 1 C(n) = C(n) + n 1 für n > 1. (10.4) Um diese Rekursionsgleichung zu lösen, betrachten wir zunächst den Fall, dass n eine Zweierpotenz ist, etwa n = q. Dann ist n genau q mal durch ohne Rest teilbar und wir erhalten durch mehrfache Anwendung der Rekursionsgleichung C(n) = C( n ) + n 1 Wegen n = q und C() = 1 folgt hieraus = C( n ) + n 1 1 mal angewendet ( = C( n 4 ) + n ) n 1 = 4 C( n ) + n 3 mal angewendet ( 4 = 4 C( n 8 ) + n ) n 3 = 8 C( n ) + 3n 7 3 mal angewendet 8... (insgesamt q 1 mal anwenden) = q 1 C() + (q 1)n ( q 1 1) C( q ) = (q 1) q + 1. Wir verifizieren diese eher intuitive Vorgehensweise durch einen formalen Beweis mit vollständiger Induktion. Lemma 10.1 Ist n = q, so hat die Rekursionsgleichung 10.4 die Lösung C( q ) = (q 1) q + 1. Beweis: Der Beweis erfolgt durch vollständige Induktion nach q. Ist q = 1, so ist C( 1 ) = 1 und (q 1) q + 1 = 1 (Induktionsanfang). Also sei die Behauptung richtig für r mit 1 r q. Wir Eine Alternative ist die Verifikation durch Einsetzen der vermuteten Formel C( q ) = (q 1) q +1 in die Rekursionsgleichung und Nachrechnen der Gleichung. Dies führt auf die gleichen Beweisschritte.

15 6 KAPITEL 10. SORTIEREN IN ARRAYS schließen jetzt auf q + 1: C( q+1 ) = C( q ) + q 1 Rekursionsgleichung = [(q 1) q + 1] + q 1 Induktionsvoraussetzung = (q 1) q q q+1 1 = q q+1 + 1, was zu zeigen war. Bezüglich der Anzahl A(n) der Zuweisungen von Arraykomponenten ergibt sich ganz analog: A(n) = A(n) + Zuweisungen in merge() In merge() werden zunächst die Teile von vec nach vec1 und vec kopiert. Dies erfordert n Zuweisungen. Für das Mergen sind dann wieder A(n, n) = n Zuweisungen erforderlich. Also ergibt sich folgende Rekursionsgleichung: Der gleiche Lösungsansatz liefert für n = q A() = 4 A(n) = A(n) + 4 n für n > 1 (10.5) A(n) = q q. Wir betrachten nun den Fall, dass n keine Zweierpotenz ist. Dann unterscheiden sich die jeweiligen Teilarrays um maximal 1, vgl. Abbildung Abbildung 10.6: Rekursionsbaum von mergesort() für n = 6. Dies führt dazu, dass im zugehörigen Rekursionsbaum nicht alle Zweige bis auf die unterste Ebene reichen. Vervollständigt man (gedanklich) den Rekursionsbaum bis auf die unterste Ebene, so würde

16 10.3. BESCHLEUNIGUNG DURCH AUFTEILUNG: DIVIDE AND CONQUER 63 dies dem Rekursionsbaum für ein Array der Länge n entsprechen, wobei n die nächstgrößere Zweierpotenz nach n ist, also n = min{ r r n, r = 1,,... Sei q dieses Minimum. Dann ist q 1 < n q = n, also n = q 1 < n sowie q 1 < logn q. Also ist (wegen der Vervollständigung): Entsprechend folgt Wir erhalten also C(n) C(n ) = C( q ) = (q 1) q + 1 < (logn) n + 1 < (logn) n + 1 = nlogn + 1 = O(nlogn). A(n) A(n ) = A( q ) = (q + 1) q < (logn + )n < (logn + )n = nlogn + 4n = O(nlogn). Satz 10.3 mergesort() sortiert ein Array mit n Komponenten mit O(n log n) Vergleichen und Zuweisungen. Betrachten wir zum Abschluss noch den Rekursionsaufwand und die Rekursionstiefe. Für n = q ist die Rekursionstiefe gerade q = log n, für beliebige n ergibt sich aus der soeben durchgeführten Vervollständigungsüberlegung logn < log(n) = logn + 1 als Schranke für die Rekursionstiefe. Die Anzahl der rekursiven Aufrufe ergibt sich als Summe entlang der Schichten des Rekursionsbaums zu q i = q+1 1 = n 1 < 4n 1 = O(n). i=0 Rekursionsaufwand und Rekursionstiefe halten sich also in vernünftigen Grenzen Beschleunigung durch Aufteilung: Divide and Conquer Mergesort ist ein typisches Beispiel für die sogenannte Beschleunigung durch Aufteilung. Dieses Prinzip tritt oft bei der Konzeption von Algorithmen auf. Daher hat man Interesse an einer allgemeinen Aussage über die Laufzeit in solchen Situationen Aufteilungs-Beschleunigungs-Sätze Gegeben ist ein Problem der Größe a n mit der Laufzeit f (a n). Dieses zerlegt man in b Teilprobleme der Größe n mit Laufzeit f (n) pro Teilproblem, also b f (n) für alle Teilprobleme zusammen. Ist die

17 64 KAPITEL 10. SORTIEREN IN ARRAYS Laufzeit für das Aufteilen und das Zusammenfügen der Teillösungen durch c n beschränkt, so ergibt sich die folgende Rekursionsgleichung und der Satz 10.4 (Aufteilungs-Beschleunigungs-Satz) Seien a > 0, b, c natürliche Zahlen und sei folgende Rekursionsgleichung gegeben: f (1) c a f (a n) b f (n) + c n für n > 1 Dann gilt: f (n) O(n) O(n log n) O(n log a b ), falls a > b, falls a = b, falls a < b Beweis:: Für n = a q gilt f (n) c a n q i=0 ( ) b i a Dies zeigt man durch Induktion über q. Für q = 0 ist die Summe 1 und daher f (1) c a. Die Behauptung sei nun für q gezeigt. Dann ergibt sich im Induktionsschluss auf q + 1: f (a q+1 ) = f (a a q ) b f (a q ) + c a q (Rekursionsformel) = b c q ( ) b i a aq + c a q (Induktionsvoraussetzung) i=0 a = c b q ( ) b i a aq+1 a + c i=0 a a aq+1 = c q ( ) b i+1 a aq+1 + c i=0 a a aq+1 ( = c q+1 ( ) b i a aq+1 + 1) i=1 a = c ( ) b i a aq+1q+1. i=0 a Also ist f (n) c a n log a n i=0 ( ) b i. a Wir betrachten jetzt 3 Fälle:

18 10.3. BESCHLEUNIGUNG DURCH AUFTEILUNG: DIVIDE AND CONQUER a > b: Dann ist b a < 1 und daher log a n i=0 ( ) b i < a i=0 ( ) b i = a a a b, da die geometrische Reihe i=0 ( b a) i wegen b a < 1 gegen k 1 := 1 1 b a f (n) < c k 1 n f (n) O(n). a. a = b: Dann ist f (n) c log a n a n 1 = c i=0 a n(log a n + 1) = c a nlog a n + c a n. Für n a ist log a n 1 und daher 3. a < b: Dann ist f (n) c a nlog a n + c a nlog a n = c a nlog a n = ( c a log a ) nlog n O(nlog n). f (n) c log a n( ) b i a n i=0 a = c q ( ) b i a aq da n = a q a i=0 q = c a i=0b i a q i = c b q i a i a i=0 = c q a ) i c a ) i a bq < i=0( b a bq. i=0( b ( a ) i i=0 b ist wie in Fall 1 eine geometrische Reihe mit Wert k = b b a. Also ist f (n) < ck a bq = ck a blog a n = c k a nlog a b O(n log ab ). Hier wurde ausgenutzt, dass b log a n = (a log a b ) log a n = (a log a n ) log a b = n log a b. q = a a b konvergiert. Also ist Die Verallgemeinerung von n = a q auf beliebige n folgt analog zu der Verallgemeinerung auf beliebige n bei Mergesort. Offenbar ist der Fall gerade der auf Mergesort zutreffende Fall. Der Aufteilungs-Beschleunigungssatz wurde hier nur in einer speziellen Form bewiesen, um den Beweis einfacher zu halten. Wir geben nachstehend eine allgemeinere Version an und verweisen für den Beweis auf [CLRS01].

19 66 KAPITEL 10. SORTIEREN IN ARRAYS Satz 10.5 (Aufteilungs-Beschleunigungs-Satz, Allgemeine Version) Seien a > 0 und b > 0 natürliche Zahlen und sei die folgende Rekursionsgleichung gegeben: f (a n) = b f (n) + g(n). Dann hat f (n) folgendes asymptotisches Wachstum: 1. Ist g(n) = O(n log a b ε ) für eine Konstante ε > 0, so ist f (n) = Θ(n log a b ).. Ist g(n) = Θ(n log a b ), so ist f (n) = Θ(n log a b logn) 3. Ist g(n) = Ω(n log a b+ε ) für eine Konstante ε > 0, und ist b g( n a ) c g(n) für eine Konstante c < 1 und alle n n 0 (c,n 0 geeignet gewählt), so ist f (n) = Θ(g(n)). Die Unterscheidung erfolgt hier also nach dem Wachstum von g(n) im Verhältnis zu n log a b. Ist g(n) deutlich kleiner als n log a b (Fall 1), so bestimmt n log a b das Wachstum von f (n). Hat g(n) dasselbe Wachstum wie n log a b (Fall ), so kommt im Wachstum von f (n) ein logn Faktor dazu. Ist schließlich g(n) deutlich größer als n log a b und gilt die zusätzliche Regularitätsbedingung aus 3., so bestimmt g(n) allein die Größenordnung von f (n). Deutlich kleiner bzw. deutlich größer bedeutet dabei jeweils mindestens um einen polynomialen Faktor n ε. Beispiel f (3n) = 9 f (n) + n Hier ergibt sich aus der einfachen Version des Satzes (Fall 3) f (n) = O(n log 3 9 ) = O(n ). In der allgemeinen Version trifft Fall 1 zu, da g(n) O(n log a b 1 ) (also ε = 1), und man erhält f (n) = Θ(n log a b ) = Θ(n ).. f ( 3 n) = f (n) + 1 Hier ist g(n) = 1 und n log 3/ 1 = n 0 = 1. Also trifft Fall der allgemeinen Version zu, und man erhält f (n) = Θ(logn). 3. f (4n) = 3 f (n) + nlogn Hier ist g(n) = nlogn und n log a b = n log 4 3 = O(n 0,793 ). Also ist g(n) = Ω(n log a b+ε ) mit ε = 0,. Es würde also Fall 3. zutreffen, falls wir die Regularitätsbedingung für g(n) zeigen können. Es ist b f ( n a ) = 3 ( ( n 4) log n ) 4 < 3 4 nlogn, so dass die Regularitätsbedingung mit c = 3 4 gilt. Also folgt f (n) = Θ(nlogn). 4. f (n) = f (n) + nlogn Diese Rekursionsgleichung fällt nicht unter das allgemeine Schema, da g(n) = n log n zwar asymptotisch größer als n log a b = n ist, aber nicht um einen Faktor n ε. Dieser Fall fällt also in die Lücke zwischen Fall. und 3.

20 10.3. BESCHLEUNIGUNG DURCH AUFTEILUNG: DIVIDE AND CONQUER Multiplikation von Dualzahlen Als weitere Anwendung betrachten wir die Multiplikation von zwei n-stelligen Dualzahlen. Die traditionelle Methode erfordert Θ(n ) Bit Operationen. Durch Aufteilung und Beschleunigung erreicht man O(n log3 ) = O(n 1,59 ) Operationen. Dies ist nützlich bei der Implementation der Multiplikation beliebig langer Dualzahlen, z. B. in Programmpaketen, die mit den Standard long oder int Zahlen nicht auskommen. Seien x,y zwei n-stellige Dualzahlen, wobei n eine Zweierpotenz sei. Wir teilen x,y in zwei n -stellige Zahlen wie folgt: x = a b y = c d Dann ist xy = (a n + b)(c n + d) = ac n + (ad + bc) n + bd. Man hat die Multiplikation also auf 4 Multiplikationen von n -stelligen Zahlen und einige Additionen und Shifts (Multiplikationen mit n bzw. n ), die nur linearen Aufwand erfordern) zurückgeführt. Dies führt zur Rekursionsgleichung T (n) = 4 T ( n ) + c 0 n, mit der Lösung T (n) = Θ(n ), also ohne Gewinn gegenüber der traditionellen Methode. Die Anweisungen u := (a + b)(c + d) v := ac w := bd z := v n + (u v w) n + w führen jedoch zur Berechnung von z = xy mit 3 Multiplikation von Zahlen der Länge n bzw. n +1, da bei a + b bzw. c + d ein Übertrag auf die ( n + 1) -te Position entstehen könnte. Ignorieren wir diesen Übertrag, so erhält man ( n T (n) = 3T + c 1 n ) mit der gewünschten Lösung T (n) = Θ(n log 3 ). Um den Übertrag zu berücksichtigen, schreiben wir a + b und c + d in der Form a + b = α ā c + d = γ c

21 68 KAPITEL 10. SORTIEREN IN ARRAYS also a + b = α n + ā, c + d = γ n + c mit den führenden Bits α,γ und den n -stelligen Resten ā, c. Dann ist (a + b)(c + d) = αγ n + (αā + γ c) n + ā c. Hierin tritt nur ein Produkt von n -stelligen Zahlen auf (nämlich ā c). Der Rest sind Shifts bzw. lineare Operationen auf n -stelligen Zahlen (z. B. αā). Daher erhält man insgesamt die Rekursionsgleichung ( n T (n) = 3T + c n, ) wobei c n folgenden Aufwand enthält: Additionen a + b, c + d : n Produkt αγ : 1 Shift von αγ auf αγ n : n Produkte αā,γ c: n n Addition αā + γ c: + 1 Shift von αā,γ c um n Stellen: n Shift von v auf v n : n Addition u v w: ( n + 1) Shift von u v w um n Stellen: n Addition zu z: n Dieser Aufwand addiert sich zu 8,5 n + 9n für n. Also kann c als 9 angenommen werden. Als Lösung erhält man nach dem Aufteilung-Beschleunigungs-Satz T (n) = Θ(n log3 ) = Θ(n 1,59 ). Der Trick bestand also darin, auf Kosten zusätzlicher Additionen und Shifts, eine teure Multiplikation von n -stelligen Zahlen einzusparen. Die rekursive Anwendung dieses Tricks ergibt dann die Beschleunigung von Θ(n ) auf Θ(n 1,59 ). Für die normale Computerarithmetik (n = 3) zahlt sich dieser Trick nicht aus, jedoch bedeutet er für Computerarithmetiken mit beliebigstelligen Dualzahlen, die meist softwaremäßig realisiert werden, eine wichtige Beschleunigung. Das Verfahren lässt sich natürlich auch im Dezimalsystem anwenden. Wir geben ein Beispiel für n = 4: x = 417 y = 536 Dann ist a = 4, b = 17 und a + b = 59; c = 5, d = 36 und c + d = 88.

22 10.4. QUICKSORT 69 Es folgt u = (a + b)(c + d) = = 519 v = ac = 4 5 = 184 w = bd = = 61 xy = v (u v w) 10 + w = = = Auf ähnliche Weise wie die Multiplikation von Zahlen lässt sich auch die Multiplikation (großer) n n Matrizen beschleunigen, vgl. [CLRS01] Hier erhält man die Rekursionsgleichung T (n) = 7 T (n) + 14n mit der Lösung (gemäß Satz 10.5) Θ(n log7 ) = Θ(n,81 ), also eine Beschleunigung gegenüber der normalen Methode mit dem Aufwand Θ(n 3 ). Hier lassen sich noch weitere Beschleunigungen erzielen. Der momentane Rekord steht bei O(n,39 ), vgl. [CW87] Quicksort Quicksort basiert (im Gegensatz zu Mergesort) auf variabler Aufteilung des Eingabearrays. Es wurde 196 von Hoare entwickelt. Es benötigt zwar im Worst Case Ω(n ) Vergleiche, im Mittel jedoch nur O(n log n) Vergleiche, und ist aufgrund empirischer Vergleiche allen anderen O(n log n) Sortierverfahren überlegen Der Algorithmus Wir geben zunächst eine Grobbeschreibung von Quicksort an. 1. Gegeben ist vec[] mit n Komponenten.. Wähle eine beliebige Komponente vec[pivot]. 3. Zerlege das Array vec in zwei Teilbereiche vec[0]...vec[k-1] und vec[k+1]...vec[n-1] mit a) vec[i].key vec[pivot].key für i = 0,...,k 1 b) vec[k].key = vec[pivot].key c) vec[j].key > vec[pivot].key für j = k + 1,...,n Sofern ein Teilbereich aus mehr als einer Komponente besteht, so wende Quicksort rekursiv auf ihn an.

23 70 KAPITEL 10. SORTIEREN IN ARRAYS Die Korrektheit des Algorithmus folgt leicht durch vollständige Induktion. Die Aufteilung erzeugt Arrays kleinerer Länge, die nach Induktionsvoraussetzung durch die Aufrufe von Quicksort in Schritt 4. korrekt sortiert werden. Die Eigenschaften 3a) 3c) ergeben dann die Korrektheit für das gesamte Array. Im Standardbeispiel ergibt sich, falls man stets die mittlere Komponente wählt (gekennzeichnet durch *) die in Abbildung 10.7 dargestellte Folge von Zuständen (jeweils nach der Aufteilung). Die umrahmten Bereiche geben die aufzuteilenden Bereiche an. Input * Aufteilung * * 63. Aufteilung * Aufteilung * Output Abbildung 10.7: Phasen bei Quicksort. Wir betrachten nun die Durchführung der Aufteilung im Detail. Da sie rekursiv auf stets andere Teile des Arrays vec angewendet wird, betrachten wir einen Bereich von lobound bis hibound. Grobbeschreibung der Aufteilung 1. Gegeben ist vec und der Bereich zwischen lobound und hibound.. Wähle eine Komponente vec[pivot]. 3. Tausche vec[pivot] mit vec[lobound]. 4. Setze Indexzeiger loswap auf lobound+1 und hiswap auf hibound. 5. Solange loswap < hiswap wiederhole: 5.1 Inkrementiere ggf. loswap solange, bis vec[loswap].key > vec[lobound].key. 5. Dekrementiere ggf. hiswap solange, bis vec[hiswap].key vec[lobound].key. 5.3 Falls loswap < hiswap, so vertausche vec[loswap] und vec[hiswap], und inkrementiere bzw. dekrementiere loswap und hiswap um jeweils Tausche vec[lobound] und vec[hiswap]. Abbildung 10.8 illustriert diese Aufteilung. l und h geben die jeweilige Position von loswap und hiswap an, das gewählte vec[pivot] Element. Bei jedem Eintritt in die Schleife 5 gilt die Invariante: vec[i].key vec[pivot].key für i = lobound...loswap 1, vec[j].key > vec[pivot].key für j = hiswap hiBound, loswap < hiswap vec[loswap-1].key vec[pivot].key vec[hiswap+1].key. (10.6)

24 10.4. QUICKSORT 71 Input Schritt * Schritt 3 53* Schritt 4 53* 4 l h Am Ende von * l h Am Ende von 5. 53* l h Schritt * l h 63 Am Ende von * l h 63 Am Ende von 5. 53* l h 63 Schritt * lh 7 63 Schritt * 7 63 Abbildung 10.8: Die Aufteilung bei Quicksort im Detail. Beim Austritt gilt zusätzlich loswap hiswap, vec[hiswap].key vec[pivot].key, (10.7) so dass der Tausch in Schritt 6 die Pivot -Komponente genau an die richtige Stelle tauscht. Lemma 10. Enthält der aufzuteilende Bereich m Komponenten, so ist die Anzahl der Vergleiche von Komponenten für die Aufteilung m 1. Beweis: Da loswap und hiswap nach einem Austausch inkrementiert bzw. dekrementiert werden, wird jedes anderen Elemente genau einmal mit dem Pivotelement verglichen. Dies ergibt m 1 Vergleiche. Es folgt eine Java Methode dieses Algorithmus. Programm 10.3 quicksort /** * Sorts with quicksort algorithm vec the array to be sorted NullPointerException if <code>vec</code> * is not initialized */ public static void quicksort(item[] vec) throws NullPointerException { if (vec == null) throw new NullPointerException(); quicksort(vec, 0, vec.length - 1);

25 7 KAPITEL 10. SORTIEREN IN ARRAYS /** * sorts array by quicksort in a certain range vec the array in which this happens lobound start of the range hibound end of the range */ private static void quicksort(item[] vec, int lobound, int hibound) { int loswap, hiswap; int pivotkey, pivotindex; Item temp, pivotitem; if (hibound - lobound == 1) { // Two items to sort if (vec[lobound].key > vec[hibound].key) { temp = vec[lobound]; vec[lobound] = vec[hibound]; vec[hibound] = temp; return; pivotindex = (lobound + hibound) / ; // 3 or more items to sort pivotitem = vec[pivotindex]; vec[pivotindex] = vec[lobound]; vec[lobound] = pivotitem; pivotkey = pivotitem.key; loswap = lobound + 1; hiswap = hibound; do { while (loswap <= hiswap && vec[loswap].key <= pivotkey) // INVARIANT (prior to test): // All vec[lobound+1..loswap-1] // are <= pivot && loswap <= hiswap+1 loswap++; while (vec[hiswap].key > pivotkey) // INVARIANT (prior to test): // All vec[hiswap+1..hibound] // are > pivot && hiswap >= loswap-1 hiswap--; if (loswap < hiswap) { temp = vec[loswap]; vec[loswap] = vec[hiswap]; vec[hiswap] = temp; loswap++; hiswap--;

26 10.4. QUICKSORT 73 // INVARIANT: All vec[lobound..loswap-1] are <= pivot // && All vec[hiswap+1..hibound] are > pivot // && (loswap < hiswap) --> // vec[loswap] <= pivot < vec[hiswap] // && (loswap >= hiswap) --> vec[hiswap] <= pivot // && lobound <= loswap <= hiswap+1 <= hibound+1 while (loswap < hiswap); vec[lobound] = vec[hiswap]; vec[hiswap] = pivotitem; if (lobound < hiswap-1) // or more items in 1st subvec quicksort(vec, lobound, hiswap-1); if (hiswap+1 < hibound) // or more items in nd subvec quicksort(vec, hiswap+1, hibound); Der Rekursionsaufwand von Quicksort Da die Aufteilung (im Unterschied zur Mergesort) variabel ist, hat der Rekursionsbaum bei Quicksort i. a. Teilbäume unterschiedlicher Höhe. Im Standardbeispiel ergibt sich der in Abbildung 10.9 dargestellte Baum. QuickSort(vec,,4) QuickSort(vec,1,4) QuickSort(vec,0,4) QuickSort(vec,0,7) Abbildung 10.9: Rekursionsbaum zu Quicksort. QuickSort(vec,6,7) Man sieht, dass der Baum am tiefsten wird, wenn als Vergleichselement jeweils das kleinste oder größte Element des aufzuteilenden Bereiches gewählt wird. In diesem Fall entartet der Rekursionsbaum zu einer Liste (keine Verzweigungen). Die Rekursionstiefe kann also bis zu n 1 betragen. Wir zeigen durch Induktion, dass auch die Anzahl R(n) der rekursiven Aufrufe bei einem Arraybereich der Länge n höchstens n 1 beträgt. Für n = 1 erfolgt kein Aufruf, also gilt R(1) = 0 (Induktionsanfang). Für n > 1 bewirkt der erste Aufruf eine Aufteilung in Bereiche mit n 1 und n Komponenten, wobei n 1 + n = n 1 gilt, da die

27 74 KAPITEL 10. SORTIEREN IN ARRAYS Vergleichskomponente weg fällt. Also sind n 1,n < n und man erhält R(n) = 1 + R(n 1 ) + R(n ) 1 + (n 1 1) + (n 1) (Induktionsvoraussetzung) = n 1 + n 1 < n 1. Also ist R(n) n Der Worst Case Aufwand von Quicksort Vergleiche von Schlüsseln treten bei Quicksort nur bei den Aufteilungen auf. Dabei muss jeder andere Schlüssel mit dem Vergleichsschlüssel verglichen werden, also erfolgen bei einem Bereich von n Komponenten mindestens (und mit Lemma 10. sogar genau) n 1 Vergleiche. Wird nun jeweils der größte bzw. kleinste Schlüsselwert als Vergleichsschlüssel gewählt, so verkleinert sich der Bereich jeweils nur um ein Element und man erhält: (n 1) + (n ) = Also gilt für die Worst Case Anzahl C(n) von Vergleichen: C(n) = Ω(n ). n(n 1) Vergleiche Der mittlere Aufwand von Quicksort Quicksort ist also im Worst Case schlecht. Erfahrungsgemäß ist Quicksort aber sehr schnell im Vergleich zu anderen Ω(n ) Sortierverfahren wie Bubblesort. Dies liegt daran, dass der Worst Case nur bei wenigen Eingabefolgen auftritt. Man wird daher Quicksort gerechter, wenn man nicht den Worst Case betrachtet, sondern den Aufwand über alle möglichen Eingabefolgen mittelt, also den mittleren Aufwand C(n) bei Gleichverteilung aller n! Reihenfolgen der Schlüssel 1,,..., n betrachtet. Gleichverteilung bedeutet hier, dass jede Reihenfolge (Permutation) der Werte 1,...,n mit dem gleichen Gewicht (nämlich 1) in das Mittel eingeht. 3 Als Vergleichsbeispiel betrachten wir das Würfeln mit einem Würfel mit den Augenzahlen 1,,...,6. Dann ergibt sich die mittlere Augenzahl bei Gleichverteilung zu = 3,5. Die mittlere Schrittlänge beim Mensch-ärgere-dich-nicht beträgt also 3, 5; der Worst Case (bzgl. Weiterkommen) jedoch nur 1. Für n = 3 ergeben sich bei Quicksort 3! = 6 Permutationen, nämlich 13, 13, 13, 31, 31, 31. Die Anzahl der Vergleiche pro Permutation beträgt (gemäß der Implementation in Programm 10.3) 3 In der Terminologie der Wahrscheinlichkeitstheorie sagt man, dass jede Reihenfolge mit der gleichen Wahrscheinlichkeit 1/n! auftritt (daher der Name Gleichverteilung), und man nennt C(n) auch die erwartete Anzahl der Vergleiche.

28 10.4. QUICKSORT 75, 4, 4, 4, 4,. Der mittlere Aufwand beträgt also Worst Case von 4 Vergleichen. 3! = 10 3 Vergleiche gegenüber dem Sei Π die Menge aller Permutationen von 1,...,n. Für π Π sei C(π) die Anzahl von Vergleichen, die Quicksort benötigt, um π zu sortieren. Dann ist C(n) = 1 n! C(π). π Π Wir werden jetzt C(n) nach oben abschätzen. Dafür teilen wir die Menge Π aller Permutationen in die Mengen Π 1,Π,...,Π n, wobei Π k = {π Π das Vergleichselement hat den Wert k. Für n = 3 ergibt sich Π 1 = {13,31, Π = {13,31 und Π 3 = {13,31. In Π k ist das Vergleichselement fest vorgeschrieben, die anderen Komponenten können jedoch in jeder Reihenfolge auftreten. Also ist Π k = (n 1)! für k = 1,...,n. Für alle π Π k ergibt die erste Aufteilung in Quicksort die Teilarrays bestehend aus einer Permutation π 1 von 1,,...,k 1 und einer Permutation π von k + 1,...,n (da ja das Vergleichselement gerade k ist). Z(π) sei die Anzahl der Vergleiche mit der π in die Teile π 1 und π zerlegt wird. Dann ist für alle π Π k C(π) = Z(π) +C(π 1 ) +C(π ). Dabei ist Z(π) n (in der Implementation in Programm 10.3, vgl. Lemma 10.). Summiert über alle π Π k, so ergibt sich wegen Π k = (n 1)!: π Π k C(π) = Hierin ist wegen Lemma 10. [Z(π) +C(π 1 ) +C(π )] = Z(π) + π Π k π Π k {{ =:S 1 S 1 π Π k n = n(n 1)! = n!. π Π k C(π 1 ) {{ =:S + π Π k C(π ) {{ =:S 3 Wenn π alle Permutationen aus Π k durchläuft, entstehen bei π 1 alle Permutationen von 1,...,k 1, und zwar jede (n 1)!/(k 1)! mal, da Π k ja insgesamt (n 1)! Permutationen enthält, und wegen der Arbeitsweise des Aufteilungsalgorithmus (und der Gleichverteilung der Permutationen in Π k jede Permutation von 1,...,k 1 gleich häufig entsteht. Also ist S = (n 1)! (k 1)! C(π 1 ) π 1 Permutation von 1,...,k 1 = (n 1)! C(k 1).

29 76 KAPITEL 10. SORTIEREN IN ARRAYS Entsprechend folgt S 3 = (n 1)! C(n k). Durch Zusammensetzen aller Gleichungen bzw. Ungleichungen ergibt sich C(n) = 1 n! C(π) = 1 n! 1 n! = n! n! π Π n k=1 n k=1 n k=1 n 1 π Π k C(π) = 1 n! n k=1 (S 1 + S + S 3 ) (n! + (n 1)! C(k 1) + (n 1)! C(n k)) 1 + (n 1)! n! = n n k=0c(k) 1 n = n + n n 1 k=0 C(k). n k=1 n 1 k=0 C(k 1) + C(k) (n 1)! n! n k=1 C(n k) Wir haben damit eine Rekursionsgleichung für C(n) gefunden. Beachtet man noch die Anfangswerte C(0) = C(1) = 0, C() = 1 so ist C(n) n + n n 1 k= C(k) für n. Lemma 10.3 Für die Lösung r(n) der Rekursionsgleichung r(n) = n + n n 1 r(k) für n k= mit den Anfangswerten r(0) = r(1) = 0, r() = 1 gilt für alle n r(n) nlnn. 4 Beweis: Der Beweis erfolgt durch vollständige Induktion nach n mit dem Ansatz r(n) nlnn, wobei die Konstante c während des Beweises ermittelt wird. Induktionsanfang: Für n = ist r() = 1. Andererseits ist c ln c 1,39. Also gilt der Induktionsanfang für c 1. Induktionsvoraussetzung: Die Behauptung gelte für, 3,..., n 1. 4 ln = log e n (natürlicher Logarithmus).

30 R(n) = n c n QUICKSORT 77 Schluss auf n: r(n) = n + n 1 n r(k) k= n + n 1 n c k ln k k= (nach Induktionsvoraussetzung) Um diesen Ausdruck weiter nach oben abzuschätzen, betrachten wir die Funktion f (x) = xlnx. Dann ist n 1 k= k lnk gerade der Flächeninhalt der schattierten Fläche unter der Kurve f (x), siehe Abbildung Also gilt: n 1 k lnk k= n = x = n xlnx dx lnx n n n x dx (partielle Integration) lnn ln [n 4 1] lnn n 4 66 KAPITEL 10. SORTIEREN IN ARRAYS f(x) = x ln x n 1 n x Abbildung Abbildung 10.10: 10.10: Verlauf Verlaufvon vonf(x) f = x ln x. x. = c n ln n + n c 4 n {{ =:R(n) c n ln n falls R(n) 0. Nun ist

31 78 KAPITEL 10. SORTIEREN IN ARRAYS Hieraus folgt Nun ist r(n) n + n n + c n n 1 c k lnk = n + c k= n ( ) n n lnn 4 = n + c c nlnn 4 n = c nlnn + n c n {{ =:R(n) c nlnn falls R(n) 0. R(n) = n c n 0 für c. n 1 k lnk k= Aus dem Lemma folgt: Satz 10.6 Für die mittlere Anzahl C(n) der Vergleiche zum Sortieren eines n-elementigen Arrays mit Quicksort gilt C(n) O(nlogn). Beweis: Aus C(n) r(n) und Lemma 10.3 folgt für alle n. C(n) nlnn = n logn loge = loge nlogn Also ist C(n) O(nlogn) mit der O-Konstanten loge 1,386. Entsprechend kann man für die mittlere Anzahl A(n) von Zuweisungen beweisen (Übung) A(n) = O(nlogn). Quicksort arbeitet also im Mittel beweisbar sehr schnell, und dies wird auch in allen Laufzeituntersuchungen bestätigt. Quicksort ist der Sortieralgorithmus, den man verwenden sollte.

32 10.5. HEAPSORT Heapsort Heapsort basiert im Gegensatz zu Mergesort und Quicksort nicht auf dem Prinzip der Aufteilung, sondern nutzt eine spezielle Datenstruktur (den Heap), mit der wiederholt auf das größte Element eines Arrays zugegriffen wird. Es ähnelt damit eher einem verbesserten Selection Sort Die Grobstruktur von Heapsort Ein Heap (auch Priority Queue genannt) ist eine abstrakte Datenstruktur mit folgenden Kennzeichen: Wertebereich: Eine Menge von Werten des (homogenen) Komponententyps. Alle Komponenten besitzen einen Wert (Schlüssel). Operationen: 1. Einfügen einer Komponente.. Zugriff auf die Komponente mit dem größten Wert. 3. Entfernen der Komponente mit dem größten Wert. 4. Änderung des Wertes einer Komponente. Statt des größten Wertes wird auch oft der kleinste Wert in. und 3. genommen. Bei der Anwendung in Heapsort sind die Komponenten von vec die Elemente des Heaps, und die Schlüssel vec[i].key sind die Werte. Dann arbeitet Heapsort nach folgender Idee: Grobstruktur von Heapsort 1. Gegeben sei das Array vec[] mit n Komponenten.. Initialisiere den Heap mit den Komponenten von vec. 3. for i := n 1 downto 0 do 3.1 Greife auf das größte Element des Heaps zu. 3. Weise diesen Wert der Arraykomponente vec[i] zu. 3.3 Entferne das größte Element aus dem Heap. Die Korrektheit des Algorithmus ist offensichtlich, und auch die Ähnlichkeit zu Selection Sort. Um zu einem schnellen Algorithmus zu kommen, muss man den Heap so implementieren, dass die benötigten Operationen schnell ausgeführt werden können. In Heapsort sind dies die Operationen (in Schritt 3.1) und 3 (in Schritt 3.3), die jeweils n mal nacheinander ausgeführt werden. Hinzu kommt das Initialisieren des Heaps in Schritt. Wir brauchen offenbar nicht alle Heapoperationen (4 wird nicht benötigt) und die anderen Operationen nur in bestimmter Reihenfolge (Einfügen nur bei der Initialisierung, Zugriff und Entfernen

33 80 KAPITEL 10. SORTIEREN IN ARRAYS stets nacheinander). Daher werden wir keinen allgemeinen Heap verwenden (vgl. dazu [CLRS01]), sondern die benötigten Heapoperationen direkt im Array vec implementieren, und zwar so, dass gilt: Worst Case-Aufwand der hier gewählten Heap Implementation Initialisierung in O(n). Zugriff auf das größte Element in O(1). Entfernen des größten Elements in O(logn). Dabei werden sowohl Vergleiche als auch Zuweisungen von Arraykomponenten berücksichtigt. Hieraus folgt sofort: Satz 10.7 Der Worst Case Aufwand zum Sortieren eines n-elementigen Arrays mit Heapsort beträgt O(nlogn) Die Implementation des Heaps Die Grundidee besteht darin, sich das Array vec als binären Baum vorzustellen, wobei die Komponenten der Reihe nach in die Schichten 0,1,... von links nach rechts angeordnet werden. Für das Standardbeispiel vec = ergibt sich so der in Abbildung dargestellte Baum Abbildung 10.11: Array als Heap. Für einen Knoten v in einem binären Baum bezeichnet man die von v aus über eine gerichtete Kante erreichbaren Knoten als Söhne und nennt v den Vater dieser Söhne. Bei Söhnen unterscheidet man (bzgl. einer gegebenen Darstellung) zwischen linkem und rechtem Sohn. Mit diesen Bezeichnungen gelten für den Baum zu einem Heap folgende Eigenschaften:

34 10.5. HEAPSORT 81 Lemma 10.4 a) vec[0] ist die Wurzel des Baumes. b) Der linke Sohn von vec[i] (falls vorhanden) ist vec[i+1]. c) Der rechte Sohn von vec[i] (falls vorhanden) ist vec[i+]. d) Nur Knoten vec[i] mit i n haben Söhne. Beweis: Übung. Wir sagen, dass vec die Heapeigenschaft (heap ordering) erfüllt, wenn für i = 0,...,n 1 gilt: vec[i].key vec[i+1].key falls i + 1 < n vec[i].key vec[i+].key falls i + < n Für jeden Knoten vec[i] mit einem oder zwei Söhnen ist also der key-wert der Söhne nicht größer als der des Vaters. Hieraus ergibt sich direkt: Lemma 10.5 Erfüllt vec die Heapeigenschaft, so gilt: a) vec[0].key ist der größte auftretende Schlüsselwert. b) Entlang jeden Weges von einem Blatt zu der Wurzel sind die Schlüsselwerte aufsteigend sortiert. Erfüllt vec die Heapeigenschaft, so kann also auf die größte Komponente vec[0] in O(1) Zeit zugegriffen werden. Wenn wir sie entfernen, so haben beide Teilbäume noch die Heapeigenschaft. Wenn wir dann ein neues Element an die Wurzel stellen (einfügen), so müssen wir die Heapeigenschaft wieder herstellen. Dazu verwenden wir die Funktion heapify(). Sie setzt voraus, dass die Heapeigenschaft bereits im Bereich vec[top+1]...vec[bottom] gilt, fügt vec[top] hinzu und ordnet die Komponenten so um, dass hinterher die Heapordnung im Bereich vec[top]...vec[bottom] gilt. Dazu werden folgende Schritte ausgeführt: 1. Ermittle den größeren der beiden Söhne (child) von top (falls keine Söhne existieren, so ist die Heapeigenschaft trivialerweise erfüllt, falls nur ein Sohn existiert, so nehme diesen).. Vergleiche vec[child] mit vec[top]. Falls vec[child].key > vec[top].key so tausche vec[top] und vec[child]. 3. Wende heapify() rekursiv auf child an.

Definition Ein Heap (priority queue) ist eine abstrakte Datenstruktur mit folgenden Kennzeichen:

Definition Ein Heap (priority queue) ist eine abstrakte Datenstruktur mit folgenden Kennzeichen: HeapSort Allgemeines Sortieralgorithmen gehören zu den am häufigsten angewendeten Algorithmen in der Datenverarbeitung. Man hatte daher bereits früh ein großes Interesse an der Entwicklung möglichst effizienter

Mehr

8. Sortieren II. 8.1 Heapsort. Heapsort. [Max-]Heap 6. Heapsort, Quicksort, Mergesort. Binärer Baum mit folgenden Eigenschaften

8. Sortieren II. 8.1 Heapsort. Heapsort. [Max-]Heap 6. Heapsort, Quicksort, Mergesort. Binärer Baum mit folgenden Eigenschaften Heapsort, Quicksort, Mergesort 8. Sortieren II 8.1 Heapsort [Ottman/Widmayer, Kap. 2.3, Cormen et al, Kap. 6] 9 210 Heapsort [Max-]Heap 6 Inspiration von Selectsort: Schnelles Einfügen Binärer Baum mit

Mehr

Heapsort, Quicksort, Mergesort. 8. Sortieren II

Heapsort, Quicksort, Mergesort. 8. Sortieren II 209 Heapsort, Quicksort, Mergesort 8. Sortieren II 210 8.1 Heapsort [Ottman/Widmayer, Kap. 2.3, Cormen et al, Kap. 6] 211 Heapsort Inspiration von Selectsort: Schnelles Einfügen Inspiration von Insertionsort:

Mehr

Datenstrukturen & Algorithmen

Datenstrukturen & Algorithmen Datenstrukturen & Algorithmen Matthias Zwicker Universität Bern Frühling 2010 Übersicht Sortieralgorithmen Einleitung Heapsort Quicksort 2 Motivation Sortieren ist Voraussetzung für viele Anwendungen Nach

Mehr

Abschnitt 19: Sortierverfahren

Abschnitt 19: Sortierverfahren Abschnitt 19: Sortierverfahren 19. Sortierverfahren 19.1 Allgemeines 19.2 Einfache Sortierverfahren 19.3 Effizientes Sortieren: Quicksort 19.4 Zusammenfassung 19 Sortierverfahren Informatik 2 (SS 07) 758

Mehr

Heapsort / 1 A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]

Heapsort / 1 A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] Heapsort / 1 Heap: Ein Array heißt Heap, falls A [i] A [2i] und A[i] A [2i + 1] (für 2i n bzw. 2i + 1 n) gilt. Beispiel: A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] Heapsort / 2 Darstellung eines Heaps als

Mehr

Kapitel 2. Weitere Beispiele Effizienter Algorithmen

Kapitel 2. Weitere Beispiele Effizienter Algorithmen Kapitel 2 Weitere Beispiele Effizienter Algorithmen Sequentielle Suche Gegeben: Array a[1..n] Suche in a nach Element x Ohne weitere Zusatzinformationen: Sequentielle Suche a[1] a[2] a[3] Laufzeit: n Schritte

Mehr

Übung Algorithmen und Datenstrukturen

Übung Algorithmen und Datenstrukturen Übung Algorithmen und Datenstrukturen Sommersemester 2017 Patrick Schäfer, Humboldt-Universität zu Berlin Agenda: Sortierverfahren 1. Schreibtischtest 2. Stabilität 3. Sortierung spezieller Arrays 4. Untere

Mehr

Kapitel 6 Elementare Sortieralgorithmen

Kapitel 6 Elementare Sortieralgorithmen Kapitel 6 Elementare Sortieralgorithmen Ziel: Kennenlernen elementarer Sortierverfahren und deren Effizienz Zur Erinnerung: Das Sortier-Problem Gegeben: Folge A von n Elementen a 1, a 2,..., a n ; Eine

Mehr

8. A & D - Heapsort. Werden sehen, wie wir durch geschicktes Organsieren von Daten effiziente Algorithmen entwerfen können.

8. A & D - Heapsort. Werden sehen, wie wir durch geschicktes Organsieren von Daten effiziente Algorithmen entwerfen können. 8. A & D - Heapsort Werden sehen, wie wir durch geschicktes Organsieren von Daten effiziente Algorithmen entwerfen können. Genauer werden wir immer wieder benötigte Operationen durch Datenstrukturen unterstützen.

Mehr

Sortieren II / HeapSort Heaps

Sortieren II / HeapSort Heaps Organisatorisches VL-07: Sortieren II: HeapSort (Datenstrukturen und Algorithmen, SS 2017) Vorlesung: Gerhard Woeginger (Zimmer 4024 im E1) Email: dsal-i1@algo.rwth-aachen.de Webseite: http://algo.rwth-aachen.de/lehre/ss17/dsa.php

Mehr

Suchen und Sortieren

Suchen und Sortieren Suchen und Sortieren Suchen Sortieren Mischen Zeitmessungen Bewertung von Sortier-Verfahren Seite 1 Suchverfahren Begriffe Suchen = Bestimmen der Position (Adresse) eines Wertes in einer Datenfolge Sequentielles

Mehr

(08 - Einfache Sortierverfahren)

(08 - Einfache Sortierverfahren) Vorlesung Informatik 2 Algorithmen und Datenstrukturen (08 - Einfache Sortierverfahren) Prof. Dr. Susanne Albers Sortieren Motivation, Einführung Datenbestände müssen sehr oft sortiert werden, etwa um

Mehr

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen Algorithmen und Datenstrukturen A7. Sortieren III Marcel Lüthi and Gabriele Röger Universität Basel 14. März 2018 Untere Schranke Sortierverfahren Sortieren Vergleichsbasierte Verfahren Nicht vergleichsbasierte

Mehr

A7.1 Untere Schranke. Algorithmen und Datenstrukturen. A7.1 Untere Schranke. Algorithmen und Datenstrukturen. A7.2 Quicksort. A7.

A7.1 Untere Schranke. Algorithmen und Datenstrukturen. A7.1 Untere Schranke. Algorithmen und Datenstrukturen. A7.2 Quicksort. A7. Algorithmen und Datenstrukturen 14. März 2018 A7. III Algorithmen und Datenstrukturen A7. III Marcel Lüthi and Gabriele Röger Universität Basel 14. März 2018 A7.1 Untere Schranke A7.2 Quicksort A7.3 Heapsort

Mehr

Informatik II, SS 2016

Informatik II, SS 2016 Informatik II - SS 2014 (Algorithmen & Datenstrukturen) Vorlesung 2 (22.4.2016) Sortieren II Algorithmen und Komplexität SelectionSort: Programm Schreiben wir doch das gleich mal als Java/C++ - Programm

Mehr

7. Sortieren Lernziele. 7. Sortieren

7. Sortieren Lernziele. 7. Sortieren 7. Sortieren Lernziele 7. Sortieren Lernziele: Die wichtigsten Sortierverfahren kennen und einsetzen können, Aufwand und weitere Eigenschaften der Sortierverfahren kennen, das Problemlösungsparadigma Teile-und-herrsche

Mehr

2 Sortieren. Beispiel: Es seien n = 8 und a = i : a i : ϕ(i) : a ϕ(i) :

2 Sortieren. Beispiel: Es seien n = 8 und a = i : a i : ϕ(i) : a ϕ(i) : 2 Sortieren Das Sortieren einer Datenfolge ist eines der am leichtesten zu verstehenden und am häufigsten auftretenden algorithmischen Probleme. In seiner einfachsten Form besteht das Problem darin, eine

Mehr

Übersicht. Datenstrukturen und Algorithmen. Übersicht. Heaps. Vorlesung 8: Heapsort (K6) Joost-Pieter Katoen. 7. Mai 2015

Übersicht. Datenstrukturen und Algorithmen. Übersicht. Heaps. Vorlesung 8: Heapsort (K6) Joost-Pieter Katoen. 7. Mai 2015 Datenstrukturen und Algorithmen Vorlesung 8: (K6) 1 Joost-Pieter Katoen Lehrstuhl für Informatik Software Modeling and Verification Group http://moves.rwth-aachen.de/teaching/ss-15/dsal/ 7. Mai 015 3 Joost-Pieter

Mehr

Algorithmen und Datenstrukturen Heapsort

Algorithmen und Datenstrukturen Heapsort Algorithmen und Datenstrukturen 2 5 Heapsort In diesem Kapitel wird Heapsort, ein weiterer Sortieralgorithmus, vorgestellt. Dieser besitzt wie MERGE-SORT eine Laufzeit von O(n log n), sortiert jedoch das

Mehr

Kapitel 10. Komplexität von Algorithmen und Sortieralgorithmen

Kapitel 10. Komplexität von Algorithmen und Sortieralgorithmen Kapitel 10 Komplexität von Algorithmen und Sortieralgorithmen Arrays 1 Ziele Komplexität von Algorithmen bestimmen können (in Bezug auf Laufzeit und auf Speicherplatzbedarf) Sortieralgorithmen kennenlernen:

Mehr

Algorithmen und Datenstrukturen 1

Algorithmen und Datenstrukturen 1 Algorithmen und Datenstrukturen 1 6. Vorlesung Martin Middendorf / Universität Leipzig Institut für Informatik middendorf@informatik.uni-leipzig.de studla@bioinf.uni-leipzig.de Merge-Sort Anwendbar für

Mehr

f 1 (n) = log(n) + n 2 n 5 f 2 (n) = n 3 + n 2 f 3 (n) = log(n 2 ) f 4 (n) = n n f 5 (n) = (log(n)) 2

f 1 (n) = log(n) + n 2 n 5 f 2 (n) = n 3 + n 2 f 3 (n) = log(n 2 ) f 4 (n) = n n f 5 (n) = (log(n)) 2 Prof. aa Dr. E. Ábrahám Datenstrukturen und Algorithmen SS Lösung - Präsenzübung.05.0 F. Corzilius, S. Schupp, T. Ströder Aufgabe (Asymptotische Komplexität): (6 + 0 + 6 = Punkte) a) Geben Sie eine formale

Mehr

Algorithmen und Datenstrukturen (Th. Ottmann und P. Widmayer) Folien: Einfache Sortierverfahren Autor: Stefan Edelkamp

Algorithmen und Datenstrukturen (Th. Ottmann und P. Widmayer) Folien: Einfache Sortierverfahren Autor: Stefan Edelkamp Algorithmen und Datenstrukturen (Th. Ottmann und P. Widmayer) Folien: Einfache Sortierverfahren Autor: Stefan Edelkamp Institut für Informatik Georges-Köhler-Allee Albert-Ludwigs-Universität Freiburg 1

Mehr

4. Sortieren 4.1 Vorbemerkungen

4. Sortieren 4.1 Vorbemerkungen . Seite 1/21 4. Sortieren 4.1 Vorbemerkungen allgemeines Sortierproblem spezielle Sortierprobleme Ordne a 1,..., a n so um, dass Elemente in aufsteigender Reihenfolge stehen. Die a i stammen aus vollständig

Mehr

Das Suchproblem. Gegeben Menge von Datensätzen. Beispiele Telefonverzeichnis, Wörterbuch, Symboltabelle

Das Suchproblem. Gegeben Menge von Datensätzen. Beispiele Telefonverzeichnis, Wörterbuch, Symboltabelle 122 4. Suchen Lineare Suche, Binäre Suche, Interpolationssuche, Untere Schranken [Ottman/Widmayer, Kap. 3.2, Cormen et al, Kap. 2: Problems 2.1-3,2.2-3,2.3-5] 123 Das Suchproblem Gegeben Menge von Datensätzen.

Mehr

Das Suchproblem. Gegeben Menge von Datensätzen. Beispiele Telefonverzeichnis, Wörterbuch, Symboltabelle

Das Suchproblem. Gegeben Menge von Datensätzen. Beispiele Telefonverzeichnis, Wörterbuch, Symboltabelle 119 4. Suchen Lineare Suche, Binäre Suche, Interpolationssuche, Exponentielle Suche, Untere Schranken [Ottman/Widmayer, Kap. 3.2, Cormen et al, Kap. 2: Problems 2.1-3,2.2-3,2.3-5] 120 Das Suchproblem Gegeben

Mehr

Algorithmen und Datenstrukturen SS09. Foliensatz 15. Michael Brinkmeier. Technische Universität Ilmenau Institut für Theoretische Informatik

Algorithmen und Datenstrukturen SS09. Foliensatz 15. Michael Brinkmeier. Technische Universität Ilmenau Institut für Theoretische Informatik Foliensatz 15 Michael Brinkmeier Technische Universität Ilmenau Institut für Theoretische Informatik Sommersemester 2009 TU Ilmenau Seite 1 / 16 Untere Schranken für das Vergleichsbasierte Sortieren TU

Mehr

Das Suchproblem 4. Suchen Das Auswahlproblem Suche in Array

Das Suchproblem 4. Suchen Das Auswahlproblem Suche in Array Das Suchproblem Gegeben. Suchen Lineare Suche, Binäre Suche, Interpolationssuche, Untere Schranken [Ottman/Widmayer, Kap. 3.2, Cormen et al, Kap. 2: Problems 2.-3,2.2-3,2.3-] Menge von Datensätzen. Beispiele

Mehr

(Digital) Sorting. October 25, Algorithms & Datastructures 2 Exercises WS 2016

(Digital) Sorting. October 25, Algorithms & Datastructures 2 Exercises WS 2016 (Digital) Sorting October 2, 2016 Algorithms & Datastructures 2 Exercises WS 2016 Dipl.-Ing. University Linz, Institute for Pervasive Computing Altenberger Straße 69, A-4040 Linz kurz@pervasive.jku.at

Mehr

Tutoraufgabe 1 (Sortieralgorithmus):

Tutoraufgabe 1 (Sortieralgorithmus): Prof. aa Dr. Ir. Joost-Pieter Katoen Datenstrukturen und Algorithmen SS Tutoriumslösung - Übung 4 (Abgabe 2..2) Christian Dehnert, Friedrich Gretz, Benjamin Kaminski, Thomas Ströder Tutoraufgabe (Sortieralgorithmus):

Mehr

Sortieralgorithmen. Selection Sort

Sortieralgorithmen. Selection Sort intuitivster Suchalgorithmus Sortieralgorithmen Selection Sort In jedem Schritt wird das kleinste Element im noch unsortierten Array gesucht und ans Ende des bisher sortierten Teilarrays gehangen 3 1 4

Mehr

Praktische Informatik I - Algorithmen und Datenstrukturen Wintersemester 2006/07

Praktische Informatik I - Algorithmen und Datenstrukturen Wintersemester 2006/07 2 Sortieren Untersuchungen haben gezeigt, dass mehr als ein Viertel der kommerziell verbrauchten Rechenzeit auf Sortiervorgänge entfällt. Sortierproblem Gegeben ist eine Folge F von Datensätzen (engl.:

Mehr

Rekursion. Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren

Rekursion. Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren Mathematische Rekursion o Viele mathematische Funktionen sind sehr natürlich rekursiv definierbar, d.h. o die

Mehr

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen Kapitel 9 Komplexität von Algorithmen und Sortieralgorithmen Arrays 1 Ziele Komplexität von Algorithmen bestimmen können (in Bezug auf Laufzeit und auf Speicherplatzbedarf) Sortieralgorithmen kennenlernen:

Mehr

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen 1 Kapitel 9 Komplexität von Algorithmen und Sortieralgorithmen Ziele 2 Komplexität von Algorithmen bestimmen können (in Bezug auf Laufzeit und auf Speicherplatzbedarf) Sortieralgorithmen kennenlernen:

Mehr

2.2 Allgemeine (vergleichsbasierte) Sortierverfahren

2.2 Allgemeine (vergleichsbasierte) Sortierverfahren . Allgemeine (vergleichsbasierte) Sortierverfahren Vergleichsbaum: Der Aufbau des Verbleichsbaum ist für jeden Algorithmus und jede Eingabelänge n gleich. Jede Permutation der Eingabe, muss zu einem anderen

Mehr

Rekursion. Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren

Rekursion. Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren Rekursion Rekursive Funktionen, Korrektheit, Terminierung, Rekursion vs. Iteration, Sortieren Mathematische Rekursion o Viele mathematische Funktionen sind sehr natürlich rekursiv definierbar, d.h. o die

Mehr

Algorithms & Data Structures 2

Algorithms & Data Structures 2 Algorithms & Data Structures Digital Sorting WS B. Anzengruber-Tanase (Institute for Pervasive Computing, JKU Linz) (Institute for Pervasive Computing, JKU Linz) WIEDERHOLUNG :: UNTERE SCHRANKE FÜR SORTIEREN

Mehr

JAVA - Suchen - Sortieren

JAVA - Suchen - Sortieren Übungen Informatik I JAVA - Suchen - Sortieren http://www.fbi-lkt.fh-karlsruhe.de/lab/info01/tutorial Übungen Informatik 1 Folie 1 Inhalt Suchen/Sortieren binary search mergesort bubblesort Übungen Informatik

Mehr

Algorithmen und Datenstrukturen 12

Algorithmen und Datenstrukturen 12 12. Juli 2012 1 Besprechung Blatt 11 Fragen 2 Binary Search Binäre Suche in Arrays Binäre Suchbäume (Binary Search Tree) 3 Sortierverfahren Allgemein Heapsort Bubblesort Insertionsort Mergesort Quicksort

Mehr

Kapitel 3: Sortierverfahren Gliederung

Kapitel 3: Sortierverfahren Gliederung Gliederung 1. Grundlagen 2. Zahlentheoretische Algorithmen 3. Sortierverfahren 4. Ausgewählte Datenstrukturen 5. Dynamisches Programmieren 6. Graphalgorithmen 7. String-Matching 8. Kombinatorische Algorithmen

Mehr

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen Algorithmen und Datenstrukturen Prof. Martin Lercher Institut für Informatik Heinrich-Heine-Universität Düsseldorf Algorithmen und Datenstrukturen Teil 3 Suchen in Listen Version vom: 15. November 2016

Mehr

1.3 Erinnerung: Mergesort

1.3 Erinnerung: Mergesort Mergesort 1.3 Erinnerung: Mergesort Um n Zahlen/Objekte a 1,..., a n zu sortieren, geht der Mergesort-Algorithmus so vor: Falls n n 0 : Sortiere mit einem naiven Algorithmus (z. B. Insertion Sort). Sonst:

Mehr

Übung: Algorithmen und Datenstrukturen SS 2007

Übung: Algorithmen und Datenstrukturen SS 2007 Übung: Algorithmen und Datenstrukturen SS 2007 Prof. Lengauer Sven Apel, Michael Claÿen, Christoph Zengler, Christof König Blatt 5 Votierung in der Woche vom 04.06.0708.06.07 Aufgabe 12 Manuelle Sortierung

Mehr

Übersicht. Datenstrukturen und Algorithmen. Übersicht. Divide-and-Conquer. Vorlesung 9: Quicksort (K7)

Übersicht. Datenstrukturen und Algorithmen. Übersicht. Divide-and-Conquer. Vorlesung 9: Quicksort (K7) Datenstrukturen und Algorithmen Vorlesung 9: (K7) Joost-Pieter Katoen Lehrstuhl für Informatik 2 Software Modeling and Verification Group http://www-i2.rwth-aachen.de/i2/dsal0/ Algorithmus 8. Mai 200 Joost-Pieter

Mehr

Elementare Sortierverfahren

Elementare Sortierverfahren Algorithmen und Datenstrukturen I Elementare Sortierverfahren Fakultät für Informatik und Mathematik Hochschule München Letzte Änderung: 18.03.2018 18:16 Inhaltsverzeichnis Sortieren.......................................

Mehr

QuickSort ist ein Sortieralgorithmus, der auf der Idee des Teile & Beherrsche beruht, und das gegebene Array an Ort und Stelle (in place) sortiert

QuickSort ist ein Sortieralgorithmus, der auf der Idee des Teile & Beherrsche beruht, und das gegebene Array an Ort und Stelle (in place) sortiert 4.3.6 QuickSort QuickSort ist ein Sortieralgorithmus, der auf der Idee des Teile & Beherrsche beruht, und das gegebene Array an Ort und Stelle (in place) sortiert QuickSort teilt das gegebene Array anhand

Mehr

lim log 2n n = > 0 Da es einen Limes gibt, gibt es auch einen Limes inferior, der gleich diesem Limes ist.

lim log 2n n = > 0 Da es einen Limes gibt, gibt es auch einen Limes inferior, der gleich diesem Limes ist. Prof. aa Dr. Ir. Joost-Pieter Katoen Christian Dehnert, Jonathan Heinen, Thomas Ströder, Sabrina von Styp Aufgabe 1 (O-Notation): Beweisen oder widerlegen Sie die folgenden Aussagen: (3 + 3 + 4 = 10 Punkte)

Mehr

Übung Algorithmen und Datenstrukturen

Übung Algorithmen und Datenstrukturen Übung Algorithmen und Datenstrukturen Sommersemester 2016 Patrick Schäfer, Humboldt-Universität zu Berlin Agenda 1. Vorstellen des vierten Übungsblatts 2. Vorbereitende Aufgaben für das vierte Übungsblatt

Mehr

Programmiertechnik II

Programmiertechnik II 2007 Martin v. Löwis Sortieren: Quicksort und Mergesort Charles Antony Richard Hoare 2007 Martin v. Löwis Geboren 11. 1. 1934 in Colombo (Sri Lanka) Studium in Oxford (Philosophie, Latein, Griechisch)

Mehr

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen Algorithmen und Datenstrukturen A3. Sortieren: Selection- und Insertionsort Marcel Lüthi and Gabriele Röger Universität Basel 1. März 2018 Sortieralgorithmen Inhalt dieser Veranstaltung A&D Sortieren Komplexitätsanalyse

Mehr

Grundlegende Sortieralgorithmen

Grundlegende Sortieralgorithmen Grundlegende Sortieralgorithmen Martin Wirsing in Zusammenarbeit mit Michael Barth, Philipp Meier und Gefei Zhang 01/05 2 Ziele Grundlegende Sortieralgorithmen auf Reihungen kennen lernen 3 Klassifizierung

Mehr

Alle bislang betrachteten Sortieralgorithmen hatten (worst-case) Laufzeit Ω(nlog(n)).

Alle bislang betrachteten Sortieralgorithmen hatten (worst-case) Laufzeit Ω(nlog(n)). 8. Untere Schranken für Sortieren Alle bislang betrachteten Sortieralgorithmen hatten (worst-case) Laufzeit Ω(nlog(n)). Werden nun gemeinsame Eigenschaften dieser Algorithmen untersuchen. Fassen gemeinsame

Mehr

Algorithmen und Datenstrukturen Wintersemester 2004/ November T(n) = T(n a) + T(a) + n

Algorithmen und Datenstrukturen Wintersemester 2004/ November T(n) = T(n a) + T(a) + n Lehrstuhl für Praktische Informatik III Norman May B6, 29, Raum C0.05 68131 Mannheim Telefon: (0621) 181 2517 Email: norman@pi3.informatik.uni-mannheim.de Matthias Brantner B6, 29, Raum C0.05 68131 Mannheim

Mehr

Kap. 3: Sortieren. Überblick. Unser Sortierproblem. Motivation. Laufzeitmessung. Warum soll ich hier bleiben? Sortierverfahren sind WICHTIG!!!

Kap. 3: Sortieren. Überblick. Unser Sortierproblem. Motivation. Laufzeitmessung. Warum soll ich hier bleiben? Sortierverfahren sind WICHTIG!!! Kap. 3: Sortieren Professor Dr. Lehrstuhl für Algorithm Engineering, LS11 Fakultät für Informatik, TU Dortmund Überblick Einführung in das Sortierproblem Insertion-Sort Selection-Sort Merge-Sort 4. VO

Mehr

Programmieren I. Kapitel 7. Sortieren und Suchen

Programmieren I. Kapitel 7. Sortieren und Suchen Programmieren I Kapitel 7. Sortieren und Suchen Kapitel 7: Sortieren und Suchen Ziel: Varianten der häufigsten Anwendung kennenlernen Ordnung Suchen lineares Suchen Binärsuche oder Bisektionssuche Sortieren

Mehr

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen Algorithmen und Datenstrukturen Große Übung #6 Phillip Keldenich, Arne Schmidt 26.02.2017 Heute: Master-Theorem Phillip Keldenich, Arne Schmidt Große Übung 2 Vorbetrachtungen Wir betrachten rekursive Gleichungen

Mehr

Gliederung. 5. Compiler. 6. Sortieren und Suchen. 7. Graphen

Gliederung. 5. Compiler. 6. Sortieren und Suchen. 7. Graphen 5. Compiler Gliederung 1. Struktur eines Compilers 2. Syntaxanalyse durch rekursiven Abstieg 3. Ausnahmebehandlung 4. Arrays und Strings 6. Sortieren und Suchen 1. Grundlegende Datenstrukturen 2. Bäume

Mehr

Praktikum Algorithmische Anwendungen WS 2006/07 Sortieren in linearer Laufzeit

Praktikum Algorithmische Anwendungen WS 2006/07 Sortieren in linearer Laufzeit Praktikum Algorithmische Anwendungen WS 2006/07 Sortieren in linearer Laufzeit Team A blau Martin Herfurth 11043831 Markus Wagner 11043447 5. Februar 2007 1 1 Untere Schranke für Vergleichsbasierte Algorithmen

Mehr

Sortieralgorithmen. Jan Pöschko. 18. Januar Problemstellung Definition Warum Sortieren?... 2

Sortieralgorithmen. Jan Pöschko. 18. Januar Problemstellung Definition Warum Sortieren?... 2 Jan Pöschko 18. Januar 2007 Inhaltsverzeichnis 1 Problemstellung 2 1.1 Definition................................... 2 1.2 Warum Sortieren?.............................. 2 2 Einfache Sortieralgorithmen

Mehr

Grundlagen: Algorithmen und Datenstrukturen

Grundlagen: Algorithmen und Datenstrukturen Technische Universität München Fakultät für Informatik Lehrstuhl für Effiziente Algorithmen Dr. Hanjo Täubig Tobias Lieber Sommersemester 2011 Übungsblatt 1 16. September 2011 Grundlagen: Algorithmen und

Mehr

Kapitel 8 Fortgeschrittene Sortieralgorithmen

Kapitel 8 Fortgeschrittene Sortieralgorithmen Kapitel 8 Fortgeschrittene Sortieralgorithmen Zur Erinnerung: in Kapitel 6 Elementare Sortierverfahren Sortierverfahren, die auf Vergleichen von Werten basieren. Aufwand zum Sortieren von Feldern von n

Mehr

8.1.3 Operation Build-Max-Heap Operation zur Konstruktion eines Heaps Eingabe: Feld A[1..n], n = länge(a) BUILD-MAX-HEAP (A)

8.1.3 Operation Build-Max-Heap Operation zur Konstruktion eines Heaps Eingabe: Feld A[1..n], n = länge(a) BUILD-MAX-HEAP (A) Stand der Vorlesung: Datenstruktur Heap: fast vollständiger Binärbaum MaxHeap: sortierter Heap, größtes Element an Wurzel Sortierverfahren: HeapSort: Sortieren eines Feldes A[1.. n] Idee: in place: Feld

Mehr

Technische Universität München

Technische Universität München Stand der Vorlesung: Datenstruktur Heap: fast vollständiger Binärbaum MaxHeap: sortierter Heap, größtes Element an Wurzel Sortierverfahren: HeapSort: Sortieren eines Feldes A[1.. n] Idee: in place: Feld

Mehr

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen Universität Innsbruck Institut für Informatik Zweite Prüfung 16. Oktober 2008 Algorithmen und Datenstrukturen Name: Matrikelnr: Die Prüfung besteht aus 8 Aufgaben. Die verfügbaren Punkte für jede Aufgabe

Mehr

Tutoraufgabe 1 (Sortieren): Lösung: Datenstrukturen und Algorithmen SS14 Lösung - Übung 4

Tutoraufgabe 1 (Sortieren): Lösung: Datenstrukturen und Algorithmen SS14 Lösung - Übung 4 Prof. aa Dr. E. Ábrahám Datenstrukturen und Algorithmen SS Lösung - Übung F. Corzilius, S. Schupp, T. Ströder Tutoraufgabe (Sortieren): a) Sortieren Sie das folgende Array durch Anwendung des Selectionsort-Algorithmus.

Mehr

Übung Algorithmen und Datenstrukturen

Übung Algorithmen und Datenstrukturen Übung Algorithmen und Datenstrukturen Sommersemester 2017 Patrick Schäfer, Humboldt-Universität zu Berlin Agenda 1. Sortierte Listen 2. Stacks & Queues 3. Teile und Herrsche Nächste Woche: Vorrechnen (first-come-first-served)

Mehr

Suchen und Sortieren (Die klassischen Algorithmen)

Suchen und Sortieren (Die klassischen Algorithmen) Suchen und Sortieren (Die klassischen Algorithmen) Lineare Suche und Binäre Suche (Vorbedingung und Komplexität) Sortieralgorithmen (allgemein) Direkte Sortierverfahren (einfach aber langsam) Schnelle

Mehr

3. Suchen. Das Suchproblem. Suche in Array. Lineare Suche. 1 n. i = n Gegeben Menge von Datensätzen.

3. Suchen. Das Suchproblem. Suche in Array. Lineare Suche. 1 n. i = n Gegeben Menge von Datensätzen. Das Suchproblem Gegeben Menge von Datensätzen. 3. Suchen Beispiele Telefonverzeichnis, Wörterbuch, Symboltabelle Jeder Datensatz hat einen Schlüssel k. Schlüssel sind vergleichbar: eindeutige Antwort auf

Mehr

in eine Folge ai, so daß bezgl. einer Ordnung gilt: a a, j < n

in eine Folge ai, so daß bezgl. einer Ordnung gilt: a a, j < n 6. Sortieren Umordnen von Objekten a in eine Folge ai,..., ai n, so daß bezgl. einer Ordnung gilt: a a, j < n Begriffe: ij i j + ) Stabilität : Ein Sortierverfahren heißt stabil, falls die relative Reihenfolge

Mehr

Grundlegende Sortieralgorithmen

Grundlegende Sortieralgorithmen Grundlegende Sortieralgorithmen Martin Wirsing in Zusammenarbeit mit Matthias Hölzl und Nora Koch Sortieren in Java Man kann Sortierverfahren in einem imperativem oder einem objektorientierten Stil programmieren.

Mehr

Algorithmen & Komplexität

Algorithmen & Komplexität Algorithmen & Komplexität Angelika Steger Institut für Theoretische Informatik steger@inf.ethz.ch Breitensuche, Tiefensuche Wir besprechen nun zwei grundlegende Verfahren, alle Knoten eines Graphen zu

Mehr

Untere Schranke für allgemeine Sortierverfahren

Untere Schranke für allgemeine Sortierverfahren Untere Schranke für allgemeine Sortierverfahren Prinzipielle Frage: wie schnell kann ein Algorithmus (im worst case) überhaupt sein? Satz: Zum einer Folge von n Keys mit einem allgemeinen Sortierverfahren

Mehr

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen 1 Algorithmen und Datenstrukturen Wintersemester 2014/15 3. Vorlesung Laufzeitanalyse Prof. Dr. Alexander Wolff Lehrstuhl für Informatik I 2 Recap: Diskutieren Sie mit Ihrer NachbarIn! 1. 2. 3. Was sind

Mehr

Übung Algorithmen I

Übung Algorithmen I Übung Algorithmen I 20.5.15 Christoph Striecks Christoph.Striecks@kit.edu (Mit Folien von Julian Arz, Timo Bingmann und Sebastian Schlag.) Roadmap Organisation Mergesort, Quicksort Dual Pivot Quicksort

Mehr

2. Grundlagen. Beschreibung von Algorithmen durch Pseudocode. Korrektheit von Algorithmen durch Invarianten.

2. Grundlagen. Beschreibung von Algorithmen durch Pseudocode. Korrektheit von Algorithmen durch Invarianten. 2. Grundlagen Beschreibung von Algorithmen durch Pseudocode. Korrektheit von Algorithmen durch Invarianten. Laufzeitverhalten beschreiben durch O-Notation. 1 Beispiel Minimum-Suche Eingabe bei Minimum

Mehr

Interne Sortierverfahren

Interne Sortierverfahren Angewandte Datentechnik Interne Sortierverfahren Interne Sortierverfahren Ausarbeitung einer Maturafrage aus dem Fach A n g e w a n d t e D a t e n t e c h n i k Andreas Hechenblaickner 5CDH HTBLA Kaindorf/Sulm

Mehr

Aufgabe 8. 1 Arbeitsweise illustrieren. 2 Korrektheitsbeweis führen. 3 Laufzeitanalyse durchführen.

Aufgabe 8. 1 Arbeitsweise illustrieren. 2 Korrektheitsbeweis führen. 3 Laufzeitanalyse durchführen. Aufgabe 8 Betrachten Sie den folgenden Algorithmus namens Bubble-Sort. Bubble-Sort(A[1..n]): 1 for i 1 to length(a) 1 2 do for j length(a) downto i + 1 3 do if A[j 1] > A[j] 4 then A[j 1] A[j] 1 Arbeitsweise

Mehr

2. Felder (Arrays) 2.1 Suchen in Feldern. lineares Suchen: siehe Kapitel 1. Binäres Suchen. Vor.: Elemente (z.b. aufsteigend) sortiert

2. Felder (Arrays) 2.1 Suchen in Feldern. lineares Suchen: siehe Kapitel 1. Binäres Suchen. Vor.: Elemente (z.b. aufsteigend) sortiert 10 2.1 Suchen in Feldern 2. Felder (Arrays) lineares Suchen: siehe Kapitel 1 Binäres Suchen Vor.: Elemente (z.b. aufsteigend) sortiert ( später) Idee: Divide & Conquer (teile und herrsche) public

Mehr

Programmiertechnik II

Programmiertechnik II Sortieren: Einfache Algorithmen Sortieren Abstrakte Operation geg: Menge von items (Elemente) jedes Element besitzt Sortierschlüssel Schlüssel unterliegen einer Ordnung eventuell sind doppelte Schlüssel

Mehr

Programmiertechnik II

Programmiertechnik II 2007 Martin v. Löwis Priority Queues and Heapsort 2007 Martin v. Löwis 2 Priority Queue Abstrakter Datentyp Inhalt: Elemente mit Priorität Operationen: Einfügen: Angabe des Elements und seiner Priorität

Mehr

Abgabe: (vor der Vorlesung) Aufgabe 2.1 (P) O-Notation Beweisen Sie die folgenden Aussagen für positive Funktionen f und g:

Abgabe: (vor der Vorlesung) Aufgabe 2.1 (P) O-Notation Beweisen Sie die folgenden Aussagen für positive Funktionen f und g: TECHNISCHE UNIVERSITÄT MÜNCHEN FAKULTÄT FÜR INFORMATIK Lehrstuhl für Sprachen und Beschreibungsstrukturen SS 2009 Grundlagen: Algorithmen und Datenstrukturen Übungsblatt 2 Prof. Dr. Helmut Seidl, S. Pott,

Mehr

Grundlagen der Informatik

Grundlagen der Informatik Jörn Fischer j.fischer@hs-mannheim.de Willkommen zur Vorlesung Grundlagen der Informatik ADS-Teil Page 2 Überblick Inhalt 1 Eigenschaften von Algorithmen Algorithmenbegriff O-Notation Entwurfstechniken

Mehr

Übungsklausur Algorithmen I

Übungsklausur Algorithmen I Jun.-Prof. Hofheinz, Jun.-Prof. Meyerhenke (ITI, KIT) 08.06.2015 Übungsklausur Algorithmen I Aufgabe 1. (Algorithm Engineering) Nennen Sie zwei Konzepte, die Algorithm Engineering im Gegensatz zu theoretischer

Mehr

Quicksort ist ein Divide-and-Conquer-Verfahren.

Quicksort ist ein Divide-and-Conquer-Verfahren. . Quicksort Wie bei vielen anderen Sortierverfahren (Bubblesort, Mergesort, usw.) ist auch bei Quicksort die Aufgabe, die Elemente eines Array a[..n] zu sortieren. Quicksort ist ein Divide-and-Conquer-Verfahren.

Mehr

2 Sortieren durch Vergleichen Eingabefolge a 1, a 2,..., a n 2, 1, 3 Sortieralg. Für festes n ist ein vergleichsbasierter Sortieralg. charakterisiert

2 Sortieren durch Vergleichen Eingabefolge a 1, a 2,..., a n 2, 1, 3 Sortieralg. Für festes n ist ein vergleichsbasierter Sortieralg. charakterisiert 1 Algorithmen und Datenstrukturen Wintersemester 2014/15 9. Vorlesung Sortieren in Linearzeit Prof. Dr. Alexander Wolff Lehrstuhl für Informatik I 2 Sortieren durch Vergleichen Eingabefolge a 1, a 2,...,

Mehr

Sortieren und Suchen. Jens Wächtler Hallo Welt! -Seminar LS 2

Sortieren und Suchen. Jens Wächtler Hallo Welt! -Seminar LS 2 Sortieren und Suchen Jens Wächtler 17.05.2017 Hallo Welt! -Seminar LS 2 Überblick Sortieren kurze Wiederholung Binäre & Ternäre Suche Binäre Suche in einer Liste Bisektionsverfahren (Nullstellensuche)

Mehr

UE Algorithmen und Datenstrukturen 1 UE Praktische Informatik 1. Übung 9. Sortieren

UE Algorithmen und Datenstrukturen 1 UE Praktische Informatik 1. Übung 9. Sortieren UE Algorithmen und Datenstrukturen 1 UE Praktische Informatik 1 Übung 9 Sortieren Institut für Pervasive Computing Johannes Kepler Universität Linz Altenberger Straße 69, A-4040 Linz Sortieren :: Problemstellung

Mehr

Praktische Informatik I - Algorithmen und Datenstrukturen Wintersemester 2006/ Algorithmen und ihre formalen Eigenschaften, Datenstrukturen

Praktische Informatik I - Algorithmen und Datenstrukturen Wintersemester 2006/ Algorithmen und ihre formalen Eigenschaften, Datenstrukturen 1 Grundlagen 1.1 Algorithmen und ihre formalen Eigenschaften, Datenstrukturen Ein Algorithmus ist ein mit formalen Mitteln beschreibbares, mechanisch nachvollziehbares Verfahren zur Lösung einer Klasse

Mehr

1 Raumwechsel: Gr. 15 (Do 10-12, F-235) ab sofort in G Studie zum Arbeitsverhalten von Studierenden unter Leitung

1 Raumwechsel: Gr. 15 (Do 10-12, F-235) ab sofort in G Studie zum Arbeitsverhalten von Studierenden unter Leitung Organisatorisches Algorithmen und Datenstrukturen Kapitel 3: Divide & Conquer Frank Heitmann heitmann@informatik.uni-hamburg.de 1 Raumwechsel: Gr. 15 (Do 10-12, F-235) ab sofort in G-021. 2 Studie zum

Mehr

Sortierverfahren für Felder (Listen)

Sortierverfahren für Felder (Listen) Sortierverfahren für Felder (Listen) Generell geht es um die Sortierung von Daten nach einem bestimmten Sortierschlüssel. Es ist auch möglich, daß verschiedene Daten denselben Sortierschlüssel haben. Es

Mehr

Übung Algorithmen und Datenstrukturen

Übung Algorithmen und Datenstrukturen Übung Algorithmen und Datenstrukturen Sommersemester 2016 Patrick Schäfer, Humboldt-Universität zu Berlin Organisation Vorlesung: Montag 11 13 Uhr Marius Kloft RUD 26, 0 115 Mittwoch 11 13 Uhr Marius Kloft

Mehr

14. Rot-Schwarz-Bäume

14. Rot-Schwarz-Bäume Bislang: Wörterbuchoperationen bei binären Suchbäume effizient durchführbar, falls Höhe des Baums klein. Rot-Schwarz-Bäume spezielle Suchbäume. Rot-Schwarz-Baum mit n Knoten hat Höhe höchstens 2 log(n+1).

Mehr

Beispiellösungen zu den Übungen Datenstrukturen und Algorithmen SS 2008 Blatt 6

Beispiellösungen zu den Übungen Datenstrukturen und Algorithmen SS 2008 Blatt 6 Robert Elsässer u.v.a. Paderborn, 29. Mai 2008 Beispiellösungen zu den Übungen Datenstrukturen und Algorithmen SS 2008 Blatt 6 Aufgabe 1 (6 Punkte): Zunächst sollte klar sein, daß ein vollständiger Binärer

Mehr

Algorithmen I. Tutorium 1-3. Sitzung. Dennis Felsing

Algorithmen I. Tutorium 1-3. Sitzung. Dennis Felsing Algorithmen I Tutorium 1-3. Sitzung Dennis Felsing dennis.felsing@student.kit.edu www.stud.uni-karlsruhe.de/~ubcqr/algo 2011-05-02 Überblick 1 Sortieren und Suchen 2 Mastertheorem 3 Datenstrukturen 4 Kreativaufgabe

Mehr

> Parallele Systeme Übung: 4. Übungsblatt Philipp Kegel Wintersemester 2012/2013. Parallele und Verteilte Systeme, Institut für Informatik

> Parallele Systeme Übung: 4. Übungsblatt Philipp Kegel Wintersemester 2012/2013. Parallele und Verteilte Systeme, Institut für Informatik > Parallele Systeme Übung: 4. Übungsblatt Philipp Kegel Wintersemester 2012/2013 Parallele und Verteilte Systeme, Institut für Informatik Inhaltsverzeichnis 2 1 Besprechung des 4. Übungsblattes Aufgabe

Mehr

Algorithmen und Datenstrukturen I Grundlagen

Algorithmen und Datenstrukturen I Grundlagen Algorithmen und Datenstrukturen I Grundlagen Prof. Dr. Oliver Braun Letzte Änderung: 01.11.2017 14:15 Algorithmen und Datenstrukturen I, Grundlagen 1/24 Algorithmus es gibt keine präzise Definition Handlungsvorschrift

Mehr

Beispiellösung zu den Übungen Datenstrukturen und Algorithmen SS 2008 Blatt 5

Beispiellösung zu den Übungen Datenstrukturen und Algorithmen SS 2008 Blatt 5 Robert Elsässer Paderborn, den 15. Mai 2008 u.v.a. Beispiellösung zu den Übungen Datenstrukturen und Algorithmen SS 2008 Blatt 5 AUFGABE 1 (6 Punkte): Nehmen wir an, Anfang bezeichne in einer normalen

Mehr

Humboldt-Universität zu Berlin Berlin, den Institut für Informatik

Humboldt-Universität zu Berlin Berlin, den Institut für Informatik Humboldt-Universität zu Berlin Berlin, den 15.06.2015 Institut für Informatik Prof. Dr. Ulf Leser Übungen zur Vorlesung M. Bux, B. Grußien, J. Sürmeli, S. Wandelt Algorithmen und Datenstrukturen Übungsblatt

Mehr