Grundlegende Sortieralgorithmen

Slides:



Advertisements
Ähnliche Präsentationen
Algorithmen und Datenstrukturen
Advertisements

Algorithmentheorie 08 – Dynamische Programmierung (1)
der Universität Oldenburg
ACM ICPC Praktikum Kapitel 4: Sortieren.
Informatik II – Kapitel 11
Einführung in die Programmierung Zusammenfassung
Lineare Suche Divide-and-Conquer-Suche Kombinationssuche
„Such-Algorithmen“ Zusammenfassung des Kapitels 11
Kapitel 7. Sortier-Algorithmen
Kapitel 3: Listen Lineare Liste: endliche Folge von Elementen eines Grundtyps (n>=0), leere Liste falls n=0 Listenelemente besitzen.
5. Sortier-Algorithmen Vorbemerkungen:
Paul, Morten, Yannick Blue J. Entwicklungsumgebung versteht Java Programmcode versteht Java Programmcode Für die Entwicklung eigener Software.
Sortierverfahren Richard Göbel.
Sortierverfahren Richard Göbel.
Java: Grundlagen der Objektorientierung
WHILE - Anweisung. Aufgabe : Ausgabe aller ganzen Zahlen von 0 bis 100 auf dem Bildschirm.
1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (02 – Funktionenklassen) Prof. Dr. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (08 - Einfache Sortierverfahren) Prof. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (02 – Funktionenklassen) Prof. Dr. Th. Ottmann.
Algorithmen und Datenstrukturen
Informatik II, SS 2008 Algorithmen und Datenstrukturen Vorlesung 9 Prof. Dr. Thomas Ottmann Algorithmen & Datenstrukturen, Institut für Informatik Fakultät.
WS Algorithmentheorie 08 – Dynamische Programmierung (3) Konstruktion optimaler Suchbäume Prof. Dr. Th. Ottmann.
PKJ 2005/1 Stefan Dissmann Ausblick Es fehlen noch: Möglichkeiten zum Strukturieren größerer Programme Umgang mit variabler Zahl von Elementen Umgang mit.
Listen Prof. Dr. Christian Böhm in Zusammenarbeit mit Gefei Zhang
Portierung von Java nach C
Vortrag: Ingo Gensch, Mathias Reich am:
Bubbelsort und Quicksort Vortrag von Rolf Heitzenröder
© 2002 Dr. Cavelius - Ley - Pohlig - Taulien Programmierung im Netz und Internet: Einführung in die Programmiersprache Java Teil I 1 Klassen Objekte von.
Einführung in die Programmierung
Einführung in die Programmierung Wintersemester 2013/14 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Programmierung Wintersemester 2013/14 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2012/13 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
4 Sortierverfahren 4.1 Einführung 4.2 Naive Sortierverfahren
Einführung in die Programmierung
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fakultät.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung Wintersemester 2011/12 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2010/11 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung
Einführung in die Programmierung Wintersemester 2012/13 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
2.4 Rekursion Klassifikation und Beispiele
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einfach und doppelt verkettete Listen in JAVA by Jens Weibler
Parameterübergabemechanismen für den Methodenaufruf
1 Albert-Ludwigs-Universität Freiburg Rechnernetze und Telematik Prof. Dr. Christian Schindelhauer Informatik III Christian Schindelhauer Wintersemester.
Sortieralgorithmen Greedy Sortieren: Sortieren durch Auswahl, Einfügen und Austauschen Divide-and-Conquer-Sortieren: Quicksort und merge sort Foliensatz.
Robuste Programme durch Ausnahmebehandlung
Vererbung Prof. Dr. Christian Böhm in Zusammenarbeit mit Gefei Zhang
Einführung in die Programmierung mit Java
M a r c – o l i v e r p a h l Informatik II – Kapitel 12 „Sortier-Algorithmen“ Zusammenfassung des Kapitel 12 Küchlin, Weber, Einführung in die Informatik,
Christos, Kornelia, Jan Christos, Kornelia, Jan Entwicklungsumgebung Versteht unseren Java Programm Code Versteht unseren Java Programm.
Sortierverfahren Mit VB 2010 express edition JBS Tr, info Q1.
Suchen und Sortieren.
 Präsentation transkript:

Grundlegende Sortieralgorithmen Prof. Dr. Christian Böhm in Zusammenarbeit mit Gefei Zhang http://www.dbs.ifi.lmu.de/Lehre/NFInfoSW

Ziele Grundlegende Sortieralgorithmen auf Reihungen kennen lernen

Klassifizierung Das Sortieren dient dem schnelleren Wiederfinden von Informationen. Beispiele für sortierte Informationsmengen: Lexika, Tabellen, Adressbücher, Kataloge usw. Man unterscheidet internes Sortieren: Die zu sortierende Folge befindet sich im Hauptspeicher (wahlfreier Zugriff) und externes Sortieren: Die zu sortierende Folge ist auf externe Speichermedien wie Bänder oder Platten ausgelagert (i.a. sequentieller Zugriff)

Sortieren in Java Man kann Sortierverfahren in einem imperativem oder einem objekt- orientierten Stil programmieren. Imperativ wählt man eine Klassenmethode und übergibt die zu sortierende Reihung als formalen Parameter, daraus resultieren folgende Methodenköpfe: static void sort (int[] a) bzw. static void sort (Object[] a)

Sortieren in Java Objekt-orientiert steht die zu sortierende Reihung in einem Attribut und man übergibt (nur) das aktuelle Objekt; man erhält folgendes Schema für eine Sortierklasse: class SortIntOO = { int[] arr; /* Gibt die aktuelle Reihung zurück **/ int[] getArray () { return arr; } /* Vertauscht die Elemente der Reihung mit den Indizes i und j void tausche(int i, int j) { int hilf = arr[i]; arr[i] = arr[j]; arr[j] = hilf; } /*Sortiert die Reihung in aufsteigender Reihenfolge void sort(){...}

Drei typische Sortieralgorithmen Direktes Aussuchen, Bubblesort, Quicksort.

Sortierproblem Sei A ein Alphabet oder eine (nicht unbedingt endliche) geordnete Menge von Elementen. Eine Folge v = v1 ... vn heißt geordnet, falls vi <= vi+1 für i = 1, ... , n-1. Sortierproblem: Gegeben sei eine Folge v = v1 ... vn in A. Ordne v so um, dass eine geordnete (oder invers geordnete) Folge entsteht. Genauer: Gesucht wird eine Permutation p : {1, ... , n}  {1, ... , n} , so dass die Folge w = v p1 ... v pn geordnet ist

Direktes Aussuchen („Select Sort“) Idee: Wiederholtes Durchsuchen des unsortierten Teils des Feldes nach dem kleinsten Element, welches dann mit dem ersten Element noch unsortierten Teils vertauscht wird. Die Länge des zu sortierenden Feldes verringert sich so bei jedem Durchlauf um eins. Bemerkung: Ist bei einem Sortierschritt das nächste Element bereits am richtigen Platz, so müßte natürlich nicht vertauscht werden. Allerdings macht die zusätzliche Abfrage das Programm langsamer, so daß man diesen (i.a. relativ seltenen) Fall besser schematisch behandelt.

Beispiel: Direktes Aussuchen („Select Sort“) 5 33 12 13 8 1 1 33 12 13 8 5 1 5 12 13 8 33 1 5 8 13 12 33 1 5 8 12 13 33 1 5 8 12 13 33

Selectsort in Java (imperativ) public static void sort (double a []) { for (int outer = 0; outer < a.length; outer++) { int min = outer; /*kleinstes Element suchen, Index nach min*/ for (int inner = outer + 1; inner < a.length; inner++) if (a[inner] < a[min]) min=inner; tausche(a, outer, min); }

Vertauschen zweier Elemente einer Reihung public static void tausche (double[] a, int i, int j) { double hilf = a[i]; a[i] = a[j]; a[j] = hilf; }

Selectsort in Java (objekt-orientiert) public class SelSortOO { private int[] arr; public SelSortOO (double[] a) { arr = a;} public double[] getArray() { return arr; } public void tausche (int i, int j) { ... } public void sort () { for (int outer = 0; outer < arr.length; outer++) { int min = outer; /*kleinstes Element suchen, Index nach min*/ for (int inner = outer + 1; inner < arr.length; inner++) if (arr[inner] < arr[min]) min=inner; tausche(outer, min); }

Aufwandsabschätzung Da das restliche Feld stets bis zum Ende durchsucht wird, ist der Aufwand nur von der Länge n der Reihung, aber nicht vom Inhalt der Reihung abhängig. Anzahl der Vergleichsoperationen: Cmax(n) = Cave(n) = Si=1 (n-i) = n(n-1) - (n/2)(n-1) = (n/2) (n-1) Î O(n2) Anzahl der Vertauschungen: Vmax(n) = Vave(n) = Si=1 1 = n-1 Î O(n) Zeitkomplexität: TwselectSort(n) = TaveselectSort(n) Î O(n2) n-1 n-1

Sortieren durch Vertauschen („Bubble Sort“) Idee: Vertausche benachbarte Elemente, wenn sie nicht wie gewünscht geordnet sind. In jedem Durchlauf des Feldes steigt das relativ größte Element wie eine "`Blase"' (bubble) im Wasser auf, was dem Verfahren seinen Namen gegeben hat.

Beispiel: „Bubble Sort“ Nach erster Runde ist das größte Element außen 5 33 12 13 8 1 5 12 13 8 1 33 Nach zwei Runden sind die beiden größten Elemente geordnet 5 12 8 1 13 33 5 8 1 12 13 33 5 1 8 12 13 33 1 5 8 12 13 33

Bubble Sort in Java public static void sort(double[] a) { for (int outer = a.length-1; outer>0; outer--) { for (int inner=0; inner<outer; inner++) { if (a[inner]>a[inner+1]) tausche(a,inner,inner+1); }

Aufwandsabschätzung Anzahl der Vergleichsoperationen (wie bei selectSort): Cmin(n) = Cmax(n) = Cave(n) = Si=1 i = (n/2) (n-1) Î O(n2) Anzahl der Vertauschungen: Schlechtester Fall: (wenn die Elemente in der falschen Reihenfolge, d.h. absteigend geordnet sind): Vmax(n) = Si=1(n-i) = n(n-1) - (n/2)(n-1) = (n/2) (n-1) Î O(n2) Durchschnittlicher Fall: Vave(n) = Si=1 (n-i)/2 = (n/4)(n-1) Î O(n2) Zeitkomplexität: TwbubbleSort(n) = TavebubbleSort(n) Î O(n2) n-1 n-1 n-1

„Quicksort (von C.A.R. Hoare)“ Quicksort ist nach Heapsort der schnellste bekannte interne Sortieralgorithmus, da Austauschen am effizientesten ist, wenn es über große Distanzen erfolgt. Idee: Man wählt aus dem Array irgendein Element als Pivot (z.B. das am weitesten rechts stehende Element) aus und läuft von der linken und der rechten Grenze der Reihung solange nach innen, bis ein nicht kleineres (auf der linken Seite) und ein nicht größeres (auf der rechten Seite) Element gefunden sind. Diese beiden werden dann vertauscht. Man wiederholt das Ganze solange, bis sich die beiden Indizes getroffen haben. Das Pivotelement wird dann in die Mitte getauscht (mit dem Element, das auf dem Platz des linken Index steht). Jetzt hat man zwei Teilfelder, wobei das eine nur Elemente kleiner oder gleich dem Grenzwert und das andere nur Elemente größer oder gleich dem Grenzwert enthält. Diese beiden Teilfelder werden entsprechend dem oben beschriebenen Algorithmus rekursiv weiter sortiert, bis nur noch einelementige und damit sortierte Teilfelder vorhanden sind.

Beispiel: „Quicksort“ 33 15 8 12 1 13 Partitionierung bilden 1 12 8 15 33 13 Pivotelement vertauschen 1 12 8 13 33 15 Linken Teil sortieren Rechten Teil sortieren 1 8 12 13 15 33

Quicksort rekursiv static void sort(double[] a) { sort(a, 0, a.length-1); } static void sort(double[] a, int left, int right) { if (right-left> 0) // nur sortieren, wenn Groesse >= 2 { double pivot = a[right]; // Element ganz rechts int partition = partitionIt(a, left, right, pivot); sort(a, left, partition-1); // sortiere linke Seite sort(a, partition+1, right); // sortiere rechte Seite

Partitionierung der Reihung public int partitionIt(double[] a, int left, int right, double pivot) { int leftPtr = left; int rightPtr = right-1; while(leftPtr<=rightPtr) { while( a[leftPtr] < pivot )leftPtr++; // finde nichtkleineres Elem while(rightPtr >=0 && a[rightPtr] > pivot) rightPtr--; // finde nichtgroesseres Elem if (leftPtr<=rightPtr) { if(leftPtr<rightPtr)tausche(a, leftPtr,rightPtr); leftPtr++;rightPtr--; } } tausche(a, leftPtr, right); // setze pivot an richtige Stelle return leftPtr; // return Index des pivot Elements

Verbesserungen des Quicksort-Algorithmus Bei kurzen Reihungen sind die einfachen Sortieralgorithmen meist besser, deshalb kann man Teilreihungen mit weniger als 10 Elementen z.B. mit SelectSort sortieren. Eine bessere Pivotbestimmung ergibt sich aus dem mittleren Wert der drei folgenden Elemente der Reihung: linkes Element, rechtes Element und das Element in der Mitte der Reihung.

O(n) Vergleiche pro Partitionierung O(n) Partitionierungen Aufwandsabschätzung O(n) Vergleiche pro Partitionierung O(n) Partitionierungen Schlechtester Fall: O(n * n) z.B. wenn die Reihung schon aufsteigend sortiert ist, gleiche Anzahl von Vergleichen wie bei SelectSort Si=1 i = (n/2) (n-1) Î O(n2) : n-1 1 5 8 12 13 33 Partitionieren 1 5 8 12 13 33 Partitionieren 1 5 8 12 13 33 Partitionieren 1 5 8 12 13 33 Partitionieren . . .

O(n) Vergleiche pro Zeile Aufwandsabschätzung O(n) Vergleiche pro Zeile O(log2 n) Zeilen Bester Fall: O(n * log n) Idee: Jede Zeile benötigt n Vergleiche, Bei Teilung der Reihung in jeweils ungefähr gleich große Hälften benötigt man log2 n Teilungen. Anzahl der Partitionen verdoppelt sich von Zeile zu Zeile, ihre Größe hal- biert sich (ungefähr). log2(n): Anzahl der Ver- dopplungen um von 1 auf n zu kommen. 1 8 5 15 13 33 12 1 8 5 12 13 33 15 1 5 8 12 13 15 33

Aufwandsabschätzung … Durchschnittlicher Fall: O(n * log n) Idee: Jede Aufteilung gleich wahrscheinlich (1:n-1, 2:n-2, 3:n-3 … n-1:1), Im Durchschnitt benötigt man etwas mehr Zeilen als im besten Fall. Man kann zeigen, dass Anzahl der Zeilen = 2*ln(n) ist, das sind 38% mehr Zeilen 1 5 12 15 13 33 8 1 5 8 15 13 33 12 1.38 * “best case“ 1 5 8 12 13 33 15 …

Zusammenfassung Sortieren durch Einfügen und Bubblesort sind Sortieralgorithmen mit quadratischer Zeit- und konstanter Speicherplatzkomplexität. Quicksort hat im Mittel die Zeitkomplexität O(n * log n). Im schlechtesten Fall ist es n2.