Algorithmen in der Java-Praxis: Teil 1

Algorithmen als Kernelemente des Programms – Definition und Klassen

Dr. Veikko Krypczyk, Olena Bochkor

© whiteMocca/Shutterstock.com

Am Anfang der Ausbildung oder des Studiums hat man sich intensiv mit Algorithmen beschäftigt. Man hat etwas über formale Anforderungen gehört und die Verfahren in Lösungsklassen eingeteilt. Danach rücken die Fragen rund um Algorithmen meist in den Hintergrund, obwohl deren Anwendung und Entwicklung der Kern einer jeden Software sind. Zeit, die Grundlagen und neuere Entwicklungen auf den aktuellen Stand zu bringen.

Ein Algorithmus beschreibt ein Verfahren, um ein bestimmtes Problem zu lösen. Bekannte Algorithmen aus der alltäglichen Programmierpraxis sind zum Beispiel Such- und Sortieralgorithmen. Neben bekannten und seit Langem etablierten Verfahren aus dieser Klasse gibt es hier auch einige neue Entwicklungen, die zum Beispiel paralleles Rechnen, d. h. die Verteilung der Arbeitslast auf mehrere Prozessoren bzw. Rechenkerne, einbeziehen. In einer vierteiligen Artikelserie wollen wir uns dem spannenden Thema Algorithmen in Theorie und Praxis nähern und neben der Auffrischung von bekanntem Wissen auch neue Entwicklungen untersuchen. Das Thema des ersten Teils ist es, Grundlagen zu Algorithmen ins Gedächtnis zurückzurufen. Wir beginnen mit den formalen Anforderungen an einen Algorithmus, sehen uns die Einteilung in Klassen an und besprechen das Vorgehen für ein eigenes Lösungsverfahren. Spezifische Algorithmen wie Such- und Sortierverfahren stehen im zweiten Teil auf der Agenda. Im dritten Teil wird es um die Fragen gehen, wie übergeordnete Algorithmen, sogenannte Metaheuristiken, dazu eingesetzt werden, sehr komplexe Probleme zu lösen. Sie kommen zum Einsatz, wenn der Lösungsraum so groß ist, dass das komplette Durchsuchen im Lösungsraum eine zu große Zeitspanne beanspruchen würde. Hier lenkt man den Algorithmus nach bestimmten Kriterien in ein passendes Suchfeld, um eine möglichst gute Lösung zu finden.

Artikelserie

  • Teil 1: Algorithmen als Kernelemente des Programms – Definition und Klassen
  • Teil 2: Such- und Sortierverfahren
  • Teil 3: Metaheuristiken zur Lösung komplexer Probleme
  • Teil 4: Ausgewählte Bibliotheken für Java – schneller in der Praxis

Die Algorithmen werden wir in Pseudocode und/oder Java darstellen. Der abschließende Teil der Serie wird sich mit ausgewählten Java-Bibliotheken beschäftigen, die in der Praxis einige schwierige Probleme schnell lösen können.

Das Thema Algorithmen ist nicht nur interessant, sondern auch hochaktuell. Big Data, künstliche Intelligenz und erweiterte Verfahren der Datenanalyse verwenden ausgewählte Algorithmen. Möchte man umfassende Datenstrukturen sortieren, muss man sich über die Effizienz des eingesetzten Verfahrens Gedanken machen (Stichwort: parallele Verarbeitung).

Definition

„Ein Algorithmus ist ein präzises festgelegtes Verfahren zur Lösung von Problemen bzw. einer Klasse von Problemen, das aus endlich vielen, effektiv ausführbaren, elementaren Lösungsschritten besteht und in endlicher Zeit aus den Eingabedaten die gewünschten Ausgabedaten produziert.“

Es muss möglich sein, einen Algorithmus wiederholt anzuwenden. Jeder Algorithmus soll folgende Bedingungen erfüllen:

  • Spezifikation: Es muss genau angegeben sein, welche Eingabedaten erforderlich sind und welche Ausgabedaten der Algorithmus generieren soll.
  • Durchführbarkeit: Das Verfahren muss vollständig beschrieben, es muss tatsächlich ausführbar sein. Die Schrittfolge des Algorithmus muss durchgängig sein und darf keine Lücken aufweisen.
  • Terminiertheit: Es muss i. d. R. feststehen, wann der Algorithmus beendet ist. Auch die längste und komplizierteste Berechnung muss ein Ende finden. Findet ein Suchalgorithmus kein Ergebnis, endet die Suche dennoch. Terminierend heißt also ausdrücklich nur, dass der Algorithmus zu einem Ende kommt, nicht, dass er erfolgreich sein muss. Hier ist zu ergänzen, dass es Algorithmen geben kann, die kein definiertes Ende haben, d. h. in einer Art Endlosschleife laufen.
  • Determiniertheit: Der Algorithmus kann wiederholt angewendet werden.
  • Korrektheit: Sind die Eingabedaten korrekt, muss der Algorithmus ein korrektes Ergebnis produzieren.
  • Jeder Softwarealgorithmus muss diese Bedingungen erfüllen, damit er als zulässig gilt. In der Regel erreicht man diese Kriterien, wenn man ein Lösungsverfahren erarbeitet, man muss sich darüber keine Gedanken machen. Wichtige Klassen von Algorithmen lösen wiederkehrende Probleme. Wir wollen uns jetzt damit beschäftigen.

Klassen von Algorithmen

Bestimmte Probleme kommen immer wieder vor und man kann erprobte Algorithmen zur Lösung einsetzen. Such- und Sortieralgorithmen sind ein solches Beispiel. Wird ein verbessertes Verfahren entwickelt, das zum Beispiel performanter arbeitet, kann man es über Bibliotheken generisch zur Verfügung stellen. Typische Klassen von Algorithmen sind beispielsweise:

  • Suchverfahren wie sequenzielle Suche, Binärsuche oder paralleles Suchen
  • Sortierverfahren wie Bubble-Sort, Insert-Sort, Quick-Sort oder Merge-Sort
  • Mathematische und numerische Algorithmen sind Verfahren, die die Schrittfolge zur Berechnung bestimmter Sachverhalte darlegen
  • Algorithmen zur Verarbeitung von Zeichenketten, z. B. Mustererkennung (Pattern Matching) und Syntaxanalyse (Parsing)
  • Algorithmen für Optimierungsverfahren optimieren eine Größe in Hinblick auf eine bestimmte Zielstellung, z. B wird der kürzeste Weg zum Gegner in einem Computerspiel oft mit Hilfe des sogenannten A*-Algorithmus gesucht
  • Geometrische Algorithmen helfen, geometrische Grundformen wie Linien oder Splines anhand bestimmter Punkte im zwei- oder dreidimensionalen Raum zu zeichnen
  • Metaheuristiken sind allgemeine, nicht problemspezifische Schemata zur Entwicklung und Steuerung heuristischer Verfahren; sie steuern andere Algorithmen von einer übergeordneten Ebene, um das Suchfeld für die Lösung einzugrenzen
  • Algorithmen der künstlichen Intelligenz generieren Aussagen auf der Basis von Datenauswertungen

Diese Liste lässt sich nahezu unendlich fortsetzen und zeigt die Breite und Tiefe des Themas.

Komplexität von Algorithmen

Deutlich schärfer ist eine Einteilung der Algorithmen im Hinblick auf ihre Komplexität. Meist besitzen die Verfahren einen Hauptparameter (N), der die Laufzeit des Algorithmus am stärksten beeinflusst. N kann z. B. die Größe einer zu sortierenden oder zu durchsuchenden Datenmenge oder die Anzahl der Knoten eines Graphen sein. Die Laufzeit des Algorithmus wird in Abhängigkeit zu N gemessen. Dabei unterscheidet man die folgenden Klassen:

  • 1: Die Laufzeit des Algorithmus ist konstant und damit unabhängig vom Parameter N. Egal wie groß das Problem ist, die Laufzeit des Algorithmus ist davon unabhängig.
  • lg N: Ist die Laufzeit eines Programms logarithmisch, wird das Programm mit größer werdendem N allmählich langsamer. Jedoch vergrößert sich die Laufzeit nicht so stark, wie die Größe des Problems zunimmt. Der Algorithmus kann also sehr große Probleme bearbeiten.
  • N ist der Normalfall. Die Laufzeit des Programms ist linear zur Größe der Problemstellung N. Verdoppelt sich die Menge der zu verarbeitenden Daten, dauert es doppelt so lange, bis das Ergebnis bestimmt ist.
  • N lg N: Die Laufzeit des Algorithmus verhält sich linearlogarithmisch zur Größe der Problemstellung N. Verdoppelt N sich, wird die Laufzeit mehr als verdoppelt.
  • N2: Die Laufzeit verhält sich quadratisch zur Größe der Problemstellung N. Typisch ist dieser Fall für die Verarbeitung von paarweisen Kombinationen von Datenelementen, z. B. in einer doppelt verschachtelten Schleife.
  • 2N: Die Laufzeit wächst exponentiell zur Größe der Problemstellung (N). Wird das Problem auch nur geringfügig größer, muss der Algorithmus ein Vielfaches an Schritten bis zur Lösung durchlaufen.

Tabelle 1 zeigt, wie sich die Laufzeit eines Algorithmus, beispielsweise anhand der Bearbeitungsschritte gemessen, bei einem Wachstum der Problemstellung (N) in Abhängigkeit der Klassenzugehörigkeit ändert.

N 1 lg N N lig N N2 2N
10 10 3 30 100 210
100 100 6 600 10000 2100
1000 1000 9 9000 1000000 21000
10000 10000 13 130000 100000000 210000
100000 100000 16 1600000 10 Milliarden 2100000
1000000 1000000 19 19000000 1 Billionen 21000000

Tabelle 1: Rechenschritte und Problemgröße bei unterschiedlicher Komplexität des Problems [1]

Nehmen wir an, wir haben ein Problem in der Größenordnung N = 10 000 und es gehört zur Komplexitätsklasse N2, dann sind 100 Millionen Rechenschritte zur Lösung des Problems nötig. Hier sieht man, dass hochkomplexe Algorithmen auch nicht von den derzeitig schnellsten Computern bearbeitet werden können. Hoffnung besteht in der Entwicklung von Quantencomputern, die aber auch einen vollständigen Wechsel bei der Entwicklung von Algorithmen bedingen würden. Es ist also sinnvoll, Zeit und Ressourcen in die Komplexitätsreduktion des Algorithmus zu investieren, um die Laufzeit zu beschleunigen.

Wie gelangt man nun zu einem Algorithmus, der durch ein Computerprogramm abgearbeitet werden kann?

Entwurf von Algorithmen

Eines steht fest, einfache Algorithmen kann man direkt in der gewählten Programmiersprache codieren. Hierzu gehören vielfältige Rechenoperationen oder auch Suchanfragen auf Datenbestände. Mit fortschreitender Erfahrung ist ein vorheriger Entwurf des Algorithmus nicht mehr notwendig. Da sich Syntax und Vorgehensweise der modernen Programmiersprachen in den letzten Jahren immer weiter angenähert haben, ist auch ein Übertragen eines Algorithmus in eine andere Programmiersprache i. d. R. problemlos möglich. Im Folgenden interessiert uns jedoch die Frage, welche Schritte empfehlenswert sind, wenn die Lösung eines Problems nicht offensichtlich ist. Das Ziel ist es, einen spezifischen Lösungsalgorithmus für eine bestimmte Frage zu entwickeln. Zwei Beispiele:

  • Bei der Programmierung eines Strategiespiels soll der Computer als Gegner gewählt werden können. Es muss ein Algorithmus entwickelt werden, der sich automatisch dem Niveau des Spielers anpasst und mit durchdachten Spielzügen auf dessen Reaktionen antwortet. Es geht also um die Entwicklung eines intelligenten Verfahrens, um in die Spielsteuerung einzugreifen.
  • Für ein Transportunternehmen soll eine Software entwickelt werden, die die Beladung der LKW plant. Dabei sind die Größe der Ladefläche, die Abmessungen der zu transportierenden Gegenstände und die Zeitpunkte der Ein- und Ausladung zu berücksichtigen.

Derartige Algorithmen kann man nicht ad hoc niederschreiben, man muss sie schrittweise entwickeln. Dabei bedient man sich der Erkenntnisse aus anderen Wissensbereichen oder allgemein formulierten Lösungsansätzen. Vielleicht hat man auch Glück und kann im einen oder anderen Fall auf eine fertige Programmbibliothek zurückgreifen. Für eine Umsetzung eines Algorithmus in der Zielsprache, aber auch für seine bloße Verwendung, muss man ihn zumindest so weit verstanden haben, dass man Einsatzzweck, Verwendung und Grenzen des Algorithmus abschätzen kann. Algorithmen, wie man sie bei Anwendungen der künstlichen Intelligenz einsetzt, sind häufig sehr komplex. Sie eigenständig zu implementieren, ist oft nicht möglich und auch nicht notwendig. Machine-Learning-Algorithmen basieren beispielsweise auf der Auswertung sehr umfassender Datensätze. Auch die zugrunde liegenden Verfahren sind aufwendig und setzen gute Statistikkenntnisse voraus. Um diese Algorithmen anzuwenden, muss man sie nicht selbst implementieren können, doch ihre grundsätzliche Arbeitsweise verstanden haben.

Systematisch vorgehen

Das Vorgehen bei der Entwicklung eines komplizierteren Algorithmus lässt sich verallgemeinern. Folgende Schritte sind empfehlenswert (Abb. 1):

Abb. 1: Systematisches Vorgehen bei der Implementierung von Algorithmen

  1. Spezifizierung der Problemstellung: Wir müssen das gegebene Problem natürlich erst einmal verstanden haben. Software beschäftigt sich mit vielfältigen Fragestellungen, daher kann es kompliziert sein, sich mit dem Problem auseinanderzusetzen, auch Hilfe von Experten kann sich als notwendig erweisen. Wenn Sie beispielsweise ein Modul für ein Rechenprogramm der Bauphysik erstellen, müssen Sie nicht Physik studieren, doch das Problem soweit durchdrungen haben, dass Sie wissen, welches Ergebnis berechnet werden soll und welche Eingabedaten zur Verfügung stehen. Ebenso ist bereits nach der grundsätzlichen Lösung für das Problem Ausschau zu halten. Gibt es einen klaren Lösungsansatz wie eine mathematische Formel, oder muss man sich mit Hilfslösungen und Näherungsverfahren behelfen? Gibt es Testdaten mit zugehörigen Inputdaten und Ergebnissen?
  2. Ausarbeitung eines Algorithmus: Es ist ein Algorithmus zu finden bzw. zu entwickeln, der durch den Rechner ausgeführt werden kann. Computerprogramme können nur streng nach vorgegebenen Ablaufstrukturen vorgehen, ein intuitives Gestalten des Lösungswegs ist nicht möglich. Am Ende dieses Schritts sollte ein spezifischer Algorithmus vorliegen. Komplizierte Algorithmen werden nicht direkt in die Zielsprache übersetzt, sondern man bedient sich unterschiedlicher Hilfsmittel. Grafisch kann man den Ablauf eines Algorithmus auf unterschiedliche Art und Weise visualisieren. Eine gebräuchliche Vorstufe der Codierung in einer Programmiersprache ist die Darstellung mit Hilfe von Pseudocode (Kasten: „Pseudocode für den schnellen Entwurf“).
  3. Analyse des Fehlerverhaltens: Insbesondere kann es bei Berechnungen zu Fehlern kommen, auch dann, wenn der eigentliche Algorithmus richtig arbeitet, aber zum Beispiel Rechenungenauigkeiten zu einem unerwünschten Verhalten führen. Unmittelbar entstehen Fehler dadurch, dass statt der exakten Werte endliche Dezimalbrüche eingesetzt werden. In Frage kommen Datentypen wie Double oder Float. Folgendes Beispiel verdeutlicht das: Für viele Berechnungen werden die trigonometrischen Funktionen wie Sinus oder Kosinus benötigt. Bekanntermaßen beträgt der exakte Wert der Sinusfunktion für die Zahl π (bzw. einem Winkel von 180°) null, also Sin(π) = 0. Diese Offensichtlichkeit kann bei einer Berechnung mit dem Computer zu Problemen führen. Wird statt π ein Näherungswert von zum Beispiel 3,14159 eingesetzt und aus dieser Zahl der Sinuswert errechnet, ergibt sich eine Abweichung. Wird auf der Basis des Ergebnisses eine Prüfung durchgeführt, zum Beispiel in der Form: if (Sinus (winkel) == 0), wird der eigentliche Programmabschnitt nicht ausgeführt, da die if-Abfrage kein positives Ergebnis liefert, denn das Ergebnis ist nicht wirklich 0. Das Programm wird nicht das gewünschte Verhalten zeigen. Diese Form von Fehlern ist unbedingt zu berücksichtigen.
  4. Analyse des Laufzeitverhaltens: Insbesondere schrittweise Verfahren können sehr schnell einen hohen Bedarf an Rechenzeit verursachen. Spielt es eine Rolle, wie viel Zeit der Algorithmus benötigt? Kann man den Anwendern das Warten zumuten? Ansatzpunkte sind beispielsweise das Auslagern eines komplexen Rechenalgorithmus in einen eigenen Thread der Anwendung. Das kann bei heutigen Mehrkernprozessoren erhebliche Vorteile bieten, wenn die anderen Programmteile nicht auf die Abarbeitung des komplexen Algorithmus warten müssen.
  5. Implementierung erfolgt in der jeweiligen Programmiersprache. Der Algorithmus muss in der Zielsprache programmiert werden. Auch wenn sich die Syntaxen vieler Sprachen immer mehr annähern, unterscheiden sie sich in wichtigen Details.
  6. Test: Dabei soll die logische Konsistenz überprüft werden. Sie müssen beispielsweise schauen, ob alle Verzweigungen im Quellcode erreicht werden. Die richtige Berechnung kann mit Hilfe von Testdaten geprüft werden.

Diese Schritte sind nicht statisch, sondern müssen an die jeweiligen Besonderheiten des Algorithmus angepasst werden. Ein systematisches Vorgehen ist auf jeden Fall zu empfehlen, da es sich oft um schwierige Probleme handelt und eine gute Lösung nicht immer offensichtlich ist. Algorithmen weisen oft komplizierte Abläufe auf, deren Verständnis durch eine visuelle Darstellung – beispielsweise durch Flussdiagramme, Struktogramme oder Aktivitätsdiagramme – deutlich verbessert werden kann.

Pseudocode für den schnellen EntwurfPseudocode ist eine Mischung aus natürlicher Sprache und einer höheren Programmiersprache. Die Beschreibung des Algorithmus gelingt exakter als bei ausschließlicher Verwendung einer natürlichen Sprache, jedoch ist man nicht an alle Zwänge der endgültigen Programmiersprache gebunden. Die technischen Facetten rücken in den Hintergrund, der Fokus liegt auf dem Fachkonzept. Pseudocode stellt ein Mittel der Kommunikation zwischen dem Fachexperten und dem Programmierer dar. Eine schrittweise Gestaltung des Übergangs von natürlicher Sprache zum Programmcode ist möglich, was insbesondere bei komplizierten Verfahren hilfreich ist. Der Pseudocode sollte selbsterklärend sein und auch ohne exakte Kenntnis der Programmiersprache verstanden werden können. Anderseits sollte es leicht möglich sein, anhand des Pseudocodes direkt die Implementierung vorzunehmen. Damit kann Pseudocode als die eigentliche Sprache für die Entwicklung von Algorithmen angesehen werden. Bei der Verwendung bedient man sich bekannter Schlüsselwörter und Konzepte, die Bestandteil vieler moderner Programmiersprachen sind:

  • Modulelemente wie Programmnamen und Klassennamen
  • Fallunterscheidungen, wie if…then …else oder switch…case
  • Funktionsaufrufe
  • Schleifen, wie repeat…until, while…do und do…while
  • Kommentare

Zu beachten ist, dass eine eindeutige Vorgabe zur Symbolik nicht existiert. Meist orientiert man sich an der Zielsprache, was jedoch zu Lasten der allgemeinen Verständlichkeit gehen kann.

Statt Pseudocode nur beim Entwurf von Algorithmen zu nutzen, kann man auch den umgekehrten Weg gehen. Gelegentlich ist es schwierig, sich in fremden Quellcode einzuarbeiten, vor allem, wenn man mit der verwendeten Programmiersprache nicht vertraut ist. In diesem Fall kann man aus dem Quellcode mit Hilfe eines Tools automatisch Pseudocode generieren. Einen Entwurf des Generators (Pseudogen) findet man auf GitHub. Dieser verarbeitet im Moment die Sprache Python.

Osteralgorithmus als Beispiel

Wann kommt der Osterhase? Am 16. April 2020. Und im nächsten Jahr? Und wann war Ostern 1988? Die Bestimmung der beweglichen Feiertage kann mit so genannten Kalenderalgorithmen erfolgen. Ausgangspunkt ist stets das Osterfest (Tabelle 2).

Feiertag/Jahr 2020 2021 2022 Abstand zu Ostersonntag(Tage)
Gründonnerstag 09.04. 01.04. 14.04. -3
Karfreitag 10.04. 02.04. 15.04. -2
Ostersonntag 12.04. 04.04. 17.04. 0
Ostermontag 13.04. 05.04. 18.04 +1
Christi Himmelfahrt 21.05. 13.05. 26.05. +39
Pfingstsonntag 31.05. 23.05. 05.06 +49
Pfingstmontag 01.06. 24.05. 06.06. +50
Fronleichnam 11.06. 03.06. 06.06. +60

Tabelle 2: Abstand der Feiertage zum Ostersonntag

Es gibt unterschiedliche Osteralgorithmen, ein bekanntes Verfahren stammt von C. F. Gauß und wurde bereits im Jahr 1800 publiziert. Dieser Algorithmus kann den Ostersonntag der Jahre von 1582 bis 2499 treffsicher bestimmen. Eine einfachere Variante des Algorithmus schränkt den Zeitraum auf 1900 bis 2099 ein, was für die meisten Fragestellungen ebenfalls genügen dürfte, und stammt von T. H. O’Beirne (Listing 1).

 
Eingabe: Jahr J: 1900…2099 
1: N = J - 1900	
2: A = N mod 19	
3: B = ((7A + 1) / 19)	
4: M = (11A + 4 - B) mod 29	
5: Q = [N / 4]	
6: W = (N + Q + 31 - M) mod 7	
7: P = 25 – M - W	
Ausgabe: Ostersonntag ist der P. April oder der (P+31). März

Nach Eingabe der Jahreszahl liefert das kleine Programm das Datum des Ostersonntags. Sie sehen, der Bruch zwischen Pseudocode und endgültigem Transfer in die Zielprogrammiersprache ist nicht groß. Dennoch hilft zunächst die Darstellung in Pseudocode, indem sie für ein besseres Verständnis des Algorithmus sorgt. Bei größeren Problemen gilt das in noch größerem Maße.

Sonderfall: Rekursive Algorithmen

Eine Rekursion ist der Aufruf einer Funktion durch sich selbst. Bei jedem rekursiven Durchlauf wird eine neue Instanz der jeweiligen Methode aufgerufen. Sie folgt dem Teile-und-herrsche-Prinzip, das Ausgangsproblem wird in mehrere kleinere Teilprobleme zerlegt. Diese Teilprobleme werden gelöst und dann die Teillösungen zu einer Gesamtlösung vereint. Eine Rekursion steht der Iteration gegenüber. Probleme können iterativ oder rekursiv gelöst werden. Oft ist die rekursive Lösung kompakter als die iterative Vorgehensweise. Der Speicherbedarf ist jedoch meist höher, da im Arbeitsspeicher der wiederholende Aufruf des gleichen Algorithmus inklusive seines Rücksprungziels für jeden Aufruf abgelegt werden muss. Ob eine rekursive Darstellung leichter verständlich ist, hängt sehr viel von der Übung ab, die man beim Entwurf rekursiver Algorithmen hat. Ein typisches Problem (akademischer Art) ist die Berechnung der Fakultät. Listing 2 zeigt den Vergleich zwischen einem iterativen Vorgehen und einem rekursiven Algorithmus in Java.

// iteratives Vorgehen 
static int fakultaetIterativ(int n) {
  int ergebnis = 1;
  for (int i = 1; i <= n; i++) {
    ergebnis = ergebnis * i;
  }
  return ergebnis;
}
// rekursives Vorgehen
static int fakultaetRekursiv(int n) {
  if (n == 1)
    return 1;
  else
    return fakultaetRekursiv(n - 1) * n;
}

Bei der Implementierung von Algorithmen muss man unbedingt auch die Paradigmen der Softwareentwicklung im Blick haben. Viele Probleme, u. a. rekursive Vorgehensweisen, lassen sich durch einen funktionalen Ansatz eleganter und vor allem mit einer kompakteren Abbildung im Quellcode lösen. Dazu werden vermehrt funktionale Sprachparadigma in Java integriert, zum Beispiel Lambdaausdrücke. Oder man setzt für den Teil der Algorithmenentwicklung auf funktionale Sprachen wie Scala.

Zusammenfassung und Ausblick

Algorithmen sind der Stoff, aus dem Software besteht. Der Entwurf und das Verständnis können kompliziert sein, wenn es darum geht, komplexe Probleme zu lösen. Gegenüber anderen Artefakten der Informatik sind sie jedoch sehr beständig, ein intelligentes Verfahren zur Lösung eines Problems kann durchaus über mehrere Jahrzehnte immer wieder angewandt werden und Programmiersprachen und Systemumgebungen überdauern. Im zweiten Teil der Artikelserie geht es um Algorithmen für das Suchen und Sortieren in Datenstrukturen. Neben bekannten Verfahren werden wir auch das Thema paralleles Sortieren angehen.

Geschrieben von
Dr. Veikko Krypczyk
Dr. Veikko Krypczyk
Dr. Veikko Krypczyk studierte und promovierte in Betriebswirtschaftslehre mit dem Schwerpunkt Wirtschaftsinformatik. Er ist Entwickler und Fachautor. Aktuell beschäftigt er sich mit der App-Programmierung für Windows Phone und Android.
Olena Bochkor
Olena Bochkor
Olena Bochkor studierte Betriebswirtschaftslehre u. a. mit dem Schwerpunkt Wirtschaftsinformatik. Weitere Informationen zu diesen und anderen Themen der IT finden Sie unter http://it-fachartikel.de.
Kommentare

1
Hinterlasse einen Kommentar

avatar
4000
1 Kommentar Themen
0 Themen Antworten
0 Follower
 
Kommentar, auf das am meisten reagiert wurde
Beliebtestes Kommentar Thema
1 Kommentatoren
Tobias Letzte Kommentartoren
  Subscribe  
Benachrichtige mich zu:
Tobias
Gast
Tobias

In der Tabelle befindet sich ein kleiner Fehler. Die Laufzeit der Spalte (1) müsste konstant verlaufen und nicht gleich N sein.