18.09.2013 Aufrufe

Ordnung muss sein: Sortieren - studiy

Ordnung muss sein: Sortieren - studiy

Ordnung muss sein: Sortieren - studiy

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

<strong>Ordnung</strong> <strong>muss</strong> <strong>sein</strong>: <strong>Sortieren</strong><br />

Wie können wir Daten sortieren? Zum Beispiel haben wir eine Liste von<br />

Personennamen und wollen diese alphabetisch sortiert haben. Zuerst werden<br />

wir per Hand probieren, wie dies gemacht werden kann. Die Grundidee: Wir<br />

haben viele Kärtchen (z.B. 10, 20, 40, 80 oder 100 Stück) mit dreistelligen<br />

Zahlen. Diese sind etwas durcheinander geraten und wir sortieren diese per<br />

Hand. Dabei wird die Zeit gemessen, wie lange dies abhängig von der Anzahl<br />

der Karten dauert.<br />

Zeichnet eine Kurve mit der Anzahl der Karten auf der x-Achse und der<br />

benötigten Sortier-Zeit in Sekunden auf der y-Achse. Ihr könnt so auch die<br />

Zeiten von mehreren Personen vergleichen. Gibt es schnellere Strategien zum<br />

<strong>Sortieren</strong>?<br />

Nun wollen wir überlegen, wie dies auf dem Computer bewerkstelligt werden<br />

kann. Auf dem Computer haben wir nur bestimmte, ausgewählte Operationen<br />

zur Verfügung. Leider lässt sich nicht alles so leicht programmieren wie wir das<br />

per Hand auf dem Tisch machen können.<br />

<strong>Sortieren</strong> stapelweise<br />

Stellen wir uns vor, wir haben Stapel zur Verfügung auf die wir nur oben was<br />

draufegen können und nur von oben wieder weg nehmen können. Des<br />

weiteren können wir zwei Stapel aufeinander stellen, wobei die Reihenfolge der<br />

Kärtchen im Stapel gleich bleibt. Reicht das zum <strong>Sortieren</strong>?<br />

Formalisieren wir zuerst unsere Pseudo-Befehle für Karten-Stapel:<br />

• leer? : ist der Stapel leer, also ohne Karten? Dann ist er schon sortiert…<br />

• drauflegen(Karte) : die Karte auf den Stapel legen<br />

• drauflegen(Stapel) : den Stapel drauf legen<br />

• runternehmen: nimmt oberste Karte vom Stapel und gibt sie als Ergebnis<br />

Quick-Sort<br />

Die Strategie ist folgende: Bei einem leeren Stapel haben wir nichts zu tun.<br />

Ansonsten nehmen wir eine Karte vom Stapel und nennen sie trennwert. Dann<br />

wird der restliche Stapel schrittweise abgebaut und zwei neue Stapel<br />

aufgebaut. In den einen kommen alle Karten kleiner als der Trennwert und in<br />

den anderen Stapel alle größeren und gleich großen. Nun wiederholen wir dies<br />

für die beiden Stapel. Diese Rekursion endet bei leeren Stapeln. Sind wir damit<br />

fertig, so wissen wir, dass beide Stapel sortiert sind. Also können wir sie einfach<br />

aufeinander legen: Zuerst der Stapel mit den kleinen Karten, dann die<br />

Trennwert-Karte, dann der Stapel mit den größeren Karten. Das Ergebnis nach<br />

dem zusammenlegen <strong>muss</strong> also wieder sortiert <strong>sein</strong> und wir sind fertig.<br />

Probiert dies per Hand mit ein paar Karten. Und klappt es? Diskutiert mit<br />

anderen oder dem Tutor wenn sich der Stapel nicht sortieren ließ.<br />

Entwerft ein Ablaufdiagramm für Quick-Sort. Es dürfte helfen, zuerst mit<br />

kleineren Teilproblemen anzufangen:


• Gegeben sei ein Stapel und der Trennwert: Wie wird der Stapel in die beiden<br />

Stapel mit kleineren und größeren Karten zerlegt?<br />

• Gegeben sei ein Stapel: Trennen, sortieren und zusammenfügen. Und keine<br />

Karte von einem leeren Stapel runternehmen!<br />

Und nun auf dem Computer<br />

Für den Vorkurs wollen wir eine vereinfachte Stapel-Klasse benutzen. Diese<br />

kann nur Zeichenketten aufnehmen. Sie heißt vk::Stapel und ist in<br />

stapel.hpp defniert (siehe auch Hilfsfunktionen für den Vorkurs (C++)).<br />

Implementiert damit den Quick-Sort-Algorithmus. Für ganz ungeduldige gibt es<br />

eine Vorlage zum einfüllen der fehlenden Teile (quicksort.cpp dort wo auch<br />

vorkurs.hpp liegt).


<strong>Sortieren</strong> der Reihe nach<br />

Legt eine Reihe Kärtchen nebeneinander. Stellt euch vor, das wir nur noch die<br />

Position von zwei Kärtchen in dieser Reihe vertauschen können, z.B. das 5. mit<br />

dem 3. Kärtchen. Dies entspricht den Vektoren (=„Arrays“) in unserer<br />

Programmiersprache. Wie können wir diesmal sortieren?<br />

Formalisieren wir zuerst unsere Pseudo-Befehle für solche Karten-Reihen:<br />

• N: ist die Anzahl der Karten<br />

• Karte[i] : das Kärtchen, dass zur Zeit an der i-ten Stelle liegt<br />

• vertausche Karte[i] Karte[j] : vertausche die beiden Karten zwischen<br />

Stelle i und j. Die anderen bleiben dort wo sie gerade liegen.<br />

Selection-Sort<br />

Wir suchen die kleinste Karte und vertauschen diese mit der ersten Karte. Nun<br />

schauen wir uns die restlichen Kärtchen ab der zweiten an. Die nun kleinste<br />

Karte wird zur 2. Stelle hin vertauscht und der Rest ab dem 3. Kärtchen<br />

angeschaut. Das geht so weiter bis wir die ganze Reihe durch sind. Probiert<br />

dies mal für eine feste Anzahl Karten aus (z.B. 50).<br />

Entwerft ein Ablaufdiagramm für diesen Algorithmus und testet ihn per Hand.<br />

Es ist sinnvoll, den Algorithmus in kleinere Teile zu zerlegen. Zum Beispiel:<br />

• Wie fnden wir die Position der kleinsten Karte von Position i bis zum Ende<br />

(N)?<br />

• Wie werden zwei Karten zwischen Position i und j getauscht?<br />

• Wie sieht die Schleife aus, um schrittweise das kleinste Kärtchen nach Vorne<br />

zu tauschen?<br />

Bubble-Sort<br />

Nicht die kleinste Suchen, sondern von Vorne nach Hinten durch die Reihe<br />

laufen. Immer wenn die aktuelle Karte größer als die nächste ist, werden beide<br />

vertauscht. Dadurch blubbern die großen Karten ans Ende der Reihe. Es wird<br />

solange über die Reihe gelaufen, bis es nichts mehr zu vertauschen gab.<br />

Entwerft ein Ablaufdiagramm für diesen Algorithmus und testet ihn per Hand.<br />

Der Algorithmus lässt sich wieder in kleinere Teile zerlegen:<br />

• von 1 bis N über die Reihe laufen und gegebenenfalls benachbarte Kärtchen<br />

vertauschen. Als Ergebnis wird zurückgegeben, ob mindestens eine<br />

Vertauschung stattfand.<br />

• solange den ersten Teil ausführen lassen, bis dieser meldet, dass nichts<br />

vertauscht wurde.<br />

Das ganze mit Vektoren in C++<br />

Nachdem Ihr die Algorithmen erfolgreich per Hand zum <strong>Sortieren</strong> angewendet<br />

habt, könnt Ihr Bubble-Sort oder Selection-Sort selber programmieren. Im<br />

folgenden Quelltext-Fragment seht ihr Beispiele zur Verwendung von Vektoren


in C++. Dafür brauchen wir #include und #include . Die<br />

Vertausche-Funktion std::swap wird mit #include importiert.<br />

Bei Fragen helfen wie immer gerne die Tutoren weiter.<br />

// ein Vektor für Zeichenketten deklarieren<br />

std::vector namen;<br />

// eine Reihe aufbauen: was anhängen<br />

namen.push_back("Meier");<br />

namen.push_back("Lügenscheidt");<br />

namen.push_back("Treufuß");<br />

// die Anzahl der Einträge erfragen<br />

int N = namen.size();<br />

// durchlaufen und ausgeben<br />

int i=0;<br />

while (i daten.txt können wir die Ausgabe des<br />

Programms generate in die Datei daten.txt schreiben.<br />

Ähnlich können wir auch die Eingabe aus einer Datei holen:<br />

quicksort < daten.txt .

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!