Programmierung mit C Algorithmen
Informationen /7/ Robert Sedgewick Algorithmen in C. 742 Seiten, ISBN 3-827-37182-1. /8/ Kyle Loudon Algorithmen mit C, ISBN 3-4897-211653-0. Online-Buch "C von A bis Z", http://www.pronix.de/pronix-4.html Programmiersprache C 26.03.07 Folie 2
Was sind Algorithmen Genau definierte Verarbeitungsvorschrift zur Lösung einer Aufgabe. Beschreibung eines Schemas, welches unter Verwendung von endlich vielen Arbeitsschritten ein bestimmtes Problem löst. Endliche Folge von Anweisungen, die nacheinander ausgeführt werden. Die Anweisungen können unter bestimmten Bedingungen wiederholt werden. Beispiele aus dem täglichen Leben: Kochrezepte Steuerprogramme für technische Geräte (z. B. Waschmaschine) Programmiersprache C 26.03.07 Folie 3
Algorithmus Ein Algorithmus benötigt endlich viele Arbeitsschritte. Ein Algorithmus ist beschreibbar. Jeder Arbeitsschritt ist ausführbar. Ein Algorithmus liefert unter identischen Startbedingungen immer das gleiche Endergebnis. Der Ablauf des Verfahrens ist eindeutig definiert. Programmiersprache C 26.03.07 Folie 4
Rekursionen Aufruf einer Funktion durch sich selbst. Jede Funktion kann sich selber wieder aufrufen. Ausnahme: main(). Jede Rekursion kann auch mit Hilfe von Schleifen realisiert werden.... benötigen eine Abbruchbedingung. Andernfalls kann es zu einem Stack Overflow kommen.... sollten nur genutzt werden,... wenn eine Lösung mit Schleifen zu kompliziert wird.... die Berechnung es erfordert. Programmiersprache C 26.03.07 Folie 5
Iterative Lösung: Fakultät int fac(int wert){ int count, antwort; antwort = 1; for (count = 1; count <= wert; count++){ antwort = antwort * count; } return(antwort); } Berechnung der Fakultät von 4: antwort = 1 * 1 => 1 antwort = 1 * 2 => 2 antwort = 2 * 3 => 6 antwort = 6 * 4 => 24 Programmiersprache C 26.03.07 Folie 6
Rekursive Lösung: Fakultät int fac(int wert){ int antwort; if (wert == 1)return(1); if (wert == 0)return(1); antwort = fact(wert 1 ) * wert; return(antwort); } Berechnung der Fakultät von 4: Aufruf von fac(4): wert > 0, Rückgabe 4 * fac(4-1) Aufruf von fac(3): wert > 0, Rückgabe 3 * fac(3-1) Aufruf von fac(2): wert > 0, Rückgabe 2 * fac(2-1) Aufruf von fac(1): wert > 0, Rückgabe 1 * fac(1-1) Aufruf von fac(0): wert = 0, Rückgabe von 1 Durch den Rekursions-Aufruf entsteht 4 * 3 * 2 * 1 = 24 Programmiersprache C 26.03.07 Folie 7
Türme von Hanoi Das Spiel besteht aus drei Stangen A, B, C. Auf der Stange A befindet sich ein Turm von n Scheiben. Die Scheiben werden von unten nach oben immer kleiner. Die Scheiben von der Stange A sollen zu der Stange C transportiert werden. Dabei sind 3 Regeln zu beachten: Es darf immer nur eine Scheibe auf einmal bewegt werden. Es darf immer nur die oberste Scheibe einer Stange genommen werden. Es darf nie eine größere Scheibe auf eine anderen liegen. Programmiersprache C 26.03.07 Folie 8
Backtracking Nutzung des Trial and Error (Versuch und Irrtum) Verfahrens. Aus verschiedenen Teillösung wird eine Lösung des Gesamtproblems abgeleitet. Falls eine Teillösung zu keinen Ergebnis führt, wird ein oder mehrere Schritte zurückgegangen. Anschließend wird versucht einen neuen Weg zu finden. Lösungen für das Problem: Finden Sie einen Weg durch einen Irrgarten. Programmiersprache C 26.03.07 Folie 9
Beispiel: Irrgarten Es wird ein Spielfeld mit Hindernissen erstellt. Die Hindernisse können mit Hilfe des ASCII-Zeichensatzes dargestellt werden. Ein Männchen bewegt sich von einer Ecke des Spielfeldrandes zur gegenüberliegenden Ecke. Bewegungen sind in der Horizontalen oder Waagerechten erlaubt. Programmiersprache C 26.03.07 Folie 10
Beispiel: Dame-Problem Ein Schachbrett besteht aus 8 x 8 Feldern. Die Dame kann sich im Schachspiel in horizontaler, vertikaler oder diagonaler Richtung bewegen. Wie müssen acht Damen auf ein Schachbrett verteilt werden, ohne das eine Dame die andere Dame bedroht? Jede Figur, die mit einer Dame in der gleichen Spalte, Reihe oder Diagonale steht, wird bedroht. Programmiersprache C 26.03.07 Folie 11
Graphische Darstellung 8 7 6 5 4 3 2 1 a b c d e f g h Programmiersprache C 26.03.07 Folie 12
Sortieren Gleichartige Informationen können nach bestimmten Kriterien sortiert werden. Buchstaben nach ihrer alphabetischen Ordnung. Zahlen nach ihrer Reihenfolge. Die Standardfunktion qsort() aus der Bibliothek stdlib.h bietet einen vordefinierten Sortieralgorithmus. Es werden nur Arrays sortiert, die sich im Hauptspeicher befinden. Verkettete Listen etc. können nicht sortiert werden. Programmiersprache C 26.03.07 Folie 13
Sortieralgorithmus Internes Sortieren... findet nur innerhalb des Arbeitsspeichers statt. Daten werden an ein Programm geschickt und sortiert ausgegeben. Externes Sortieren... findet auf Festplatten etc. statt.... benötigt Lese- und Schreibzugriffe auf den externen Medien. Vergleichendes Sortieren Eine Menge von Daten wird anhand von Schlüsselfeldern nach bestimmten Kriterien sortiert. Die verschiedenen Schlüsselfelder können mit Hilfe von Vergleichsoperatoren sortiert werden. In Abhängigkeit der Schlüsselfelder wird die gesamte Datenstruktur sortiert. Stabiles Sortieren Eine Kundenliste wird nach dem Ort sortiert. Innerhalb dieser Sortierung wird nach dem Namen des Kunden sortiert. Die Sortierung nach dem Namen zerstört nicht die Sortierung nach dem Ort. Die Liste wird nach und nach anhand von bestimmten Kriterien sortiert. Programmiersprache C 26.03.07 Folie 14
Bewertung von Algorithmen Wie schnell kann der Algorithmus in durchschnittlichen Fällen Daten sortieren? Wie schnell ist der Algorithmus im besten und schlechtesten Fall? Die Geschwindigkeit ist abhängig von der Anzahl der aktuellen Vergleiche und Austauschvorgänge. Ein Vergleich findet statt, wenn ein Element mit einem anderen verglichen wird. Ein Austausch findet statt, wenn zwei Elemente miteinander vertauscht werden. Die Austauschvorgänge erfordern dabei etwas mehr Zeit. Bei manchen Sortierroutinen steigt die Laufzeit exponentiell zur Anzahl der zu sortierenden Elemente. Bei einigen anderen steigt die Laufzeit logarithmisch an. Zeigt der Algorithmus ein natürliches oder unnatürliches Verhalten? Der Algorithmus arbeitet wenig, wenn die Liste sortiert ist. Der Algorithmus arbeitet etwas mehr, wenn die Liste nur in Teilen sortiert ist. Der Algorithmus arbeitet am meisten, wenn die Liste in umgekehrter Sortierreihenfolge angeordnet ist. Ordnet er Elemente mit gleichen Schlüssel erneut an? Programmiersprache C 26.03.07 Folie 15
Sortieren durch Auswählen Sie werfen ein Kartenspiel mit dem Bild nach oben auf dem Tisch, suchen die niedrigste Karte mit den niedrigsten Wert heraus und nehmen Sie in die Hand. Dann wählen Sie aus dem Kartenhaufen die nächste Karte mit den niedrigsten Wert und stecken diese hinter diejenige Karte, die sich bereits in Ihrer Hand befindet. Diesen Vorgang wiederholen Sie solange, bis sich alle Karten in Ihrer Hand befinden. Einfügen Sie halten das Kartenspiel unsortiert in der Hand. Dann legen Sie immer eine Karte auf einmal auf den Tisch ab und fügen Sie dabei gleich an die richtige Stelle ein. Der Kartenstapel liegt vollständig sortiert auf dem Tisch, wenn Sie keine Karten mehr auf der Hand haben. Vertauschen Sie werfen ein Kartenspiel mit dem Bild nach oben auf dem Tisch und tauschen dann die nicht in der richtigen Reihenfolge liegenden Karten so lange aus, bis alle Karten richtig im Stapel liegen. Programmiersprache C 26.03.07 Folie 16
Sortieren durch Auswählen Das Element mit dem niedrigsten Wert wird ausgewählt und mit dem ersten Element vertauscht. Dann wird in der verbleibenden Menge wieder nach dem Element mit dem niedrigsten Wert gesucht und dieser mit dem zweiten Element vertauscht und so weiter. Der Austausch wird bis zu den letzten beiden Elementen fortgesetzt. Programmiersprache C 26.03.07 Folie 17
Ablauf D C A B ptr A C D B A B D C A B C D Programmiersprache C 26.03.07 Folie 18
Bubble Sort Bekannteste Algorithmus und einfach zu implementieren. Arbeitsweise: Das Array wird vollständig durchlaufen. Wenn nötig, werden benachbarte Elemente getauscht. Programmiersprache C 26.03.07 Folie 19
Ablauf D C A B if(element[ptr - 1] > element[ptr]) ptr D C A B D A C B A D C B Programmiersprache C 26.03.07 Folie 20
Sortieren durch Einfügen Die Elemente werden von vorn nach hinten durchlaufen. Jedes Element wird von rechts nach links weitergereicht. Sobald das wandernde Element größer gleich als die abgefragte Position ist, wird abgebrochen. Programmiersprache C 26.03.07 Folie 21
Ablauf D C A B ptr C D A B C A D B A C D B Programmiersprache C 26.03.07 Folie 22
Shellsort... ist benannt nach den Erfinder D. L. Shell.... ist eine Ableitung von "Sortieren durch Einfügen".... vergleicht nur jedes n-te-element mit einem anderen Element. Das Anfangselement kann beliebig gesetzt werden. Basiert auf abnehmenden Inkrementen. Diese Inkremente bestimmen in welcher Abfolge die Elemente verglichen und sortiert werden. Die Abfolge der Inkrementierung kann verändert werden. Die letzte Inkrementierung muss den Wert 1 haben. Vermeiden Sie Abfolgen, die Potenzen aus 2 darstellen, um die Effizienz des Algorithmus nicht zu verminderen. Programmiersprache C 26.03.07 Folie 23
Ablauf F D A C B E Im ersten Durchlauf werden alle Elemente mit Elementen an der Position + 3 vertauscht. C B A F D E Im zweiten Durchlauf werden alle Elemente mit Elementen an der Position + 2 vertauscht. A B C E D F Falls nötig, werden die Elemente mit ihren Nachbarn getauscht. A B C D E F Programmiersprache C 26.03.07 Folie 24
Quicksort... wurde erfunden von C. A. R. Hoare.... ist ein Allzweck-Algorithmus.... basiert auf das Sortieren durch Austauschen. Arbeitsweise: Es wird ein Vergleichswert ausgewählt und das Feld dann in zwei Felder geteilt. Alle Elemente die größer oder gleich dem Vergleichswert sind, werden dann auf die eine Seite und alle Elemente, die kleiner als Vergleichswert sind, auf die andere Seite gelegt. Dieser Vorgang wird für die verbleibende Felder so lange fortgesetzt, bis das Array sortiert ist.... arbeitet nach dem Prinzip "Teile und Herrsche".... ist immer rekursiv.... ist mit Hilfe von der Funktion qsort() in der Standard-Bibliothek stdlib.h implementiert. Programmiersprache C 26.03.07 Folie 25
Vergleichswert auswählen Optimal ist ein Wert der präzise in der Mitte des Wertebereichs befindet. Der Algorithmus wird sehr langsam, wenn als Vergleichswert zufällig der größte Wert ausgewählt wird. Auswahlverfahren: Bei einer gleichmäßigen Verteilung kann mit Hilfe einer Algebra-Funktion ein Vergleichswert gefunden werden. Bei einer ungeraden Zahl von Werten kann der mittlere Wert genutzt werden. Programmiersprache C 26.03.07 Folie 26