Springe zum Inhalt oder Footer
SerloDie freie Lernplattform

Kurs

Datenstrukturen und Algorithmen

1 Was ist ein Algorithmus?

Gibst du diese Frage in Google ein, wirst du zwar viele Erklärungen finden, meist sind sie jedoch schwer verständlich. Das liegt daran, dass sie eher wissenschaftlich korrekt sein sollen, als Anfängern einen guten Einstieg in das Thema zu geben. Man kann das Wort „Algorithmus“ jedoch auch sehr einfach übersetzen: Liste von Befehlen.

Diese "Liste" ist quasi ein Kochrezept für den Computer, aber anstatt irgendwelche Zutaten in richtiger Reihenfolge zu vermischen, werden verschiedene Berechnungen durchgeführt. Dabei ist der Computer ziemlich einfach gestrickt, er fängt ganz oben an und arbeitet sich mehr oder weniger geradlinig nach unten durch. Aber wie sieht so eine Aufgabenliste, also ein Algorithmus, denn genau aus?

Das ist das eigentlich Interessante, das entscheidest nämlich du durch deine Programmierung. Dabei stehen dir diverse Werkzeuge zur Verfügung, die du auf den nächsten Seiten kennenlernen wirst.

Zusammenfassung:

  • Ein Algorithmus ist eine Liste von Befehlen, die dein Computer abarbeitet

  • Diese Liste wird von oben nach unten bearbeitet

  • Den Inhalt dieser Liste legst du beim Programmieren fest

Was verbirgt sich hinter der coolen bunten Schrift?

2 Programmiersprachen & Werkzeuge

Vielleicht hast du schon von Programmiersprachen gelesen oder gehört. Aber was verbirgt sich hinter Wörtern wie „Java“ oder „Python“?

Du und dein Computer, ihr sprecht nicht dieselbe Sprache. Du benutzt Wörter, um mit anderen Menschen zu sprechen. Die Sprache deines Computers ist erstmal auf zwei Symbole eingeschränkt: 0 und 1. Aber mithilfe von Programmiersprachen trefft ihr euch sozusagen in der Mitte. Du kannst es lesen und mit etwas Hilfe von bestimmten Programmen versteht es auch der Computer.

In diesen Programmiersprachen verfasst du also den Algorithmus mit Anweisungen, die dein Computer stumpf abarbeitet. Die gute Nachricht: Auch wenn es mehrere hundert Programmiersprachen gibt, ihre Grundlagen sind sich sehr ähnlich. Wenn du dir also einmal die Arbeit gemacht hast, eine Programmiersprache zu lernen, wird es dir leicht fallen, weitere zu lernen.

Deshalb ist das Ziel von diesem Kurs auch nicht, dir eine bestimmte Programmiersprache beizubringen. Vielleicht lernst du ja sogar gerade eine Programmiersprache wie Java mithilfe von Onlinetutorials oder in der Schule, aber hast hier und da bei den Grundbegriffen Verständnisprobleme. Dann ist dieser Kurs genau das Richtige für dich!

Zusammenfassung:

  • Um unsere Befehle für den Computerlesbar zu machen, benutzen wir sogenannte Programmiersprachen

  • Die Grundlagen der meisten Programmiersprachen sind sehr ähnlich

3 Variablen

Die gute Nachricht zuerst: Hier geht es nicht um dieselben Variablen, wie im Mathematikunterricht, und um deren lange Berechnung. Auch wenn der grundlegende Gedanke ähnlich ist:

Eine Variable ist irgendetwas Beliebiges, etwas, das du definierst, ganz nach deinem Wunsch. Stell dir vor, du stehst vor einem Regal, es ist aber aktuell völlig leer. Erst füllst du dieses Regal mit Boxen, und wenn du eine Information aus einer dieser Boxen willst, musst du nur den Namen der Box wissen, um nachzuschauen. Als Beispiel legen wir jetzt drei davon an.

Box #1 trägt den Titel „Mein Vorname“, darin steht nichts außer deinen Vornamen. Box #2 heißt „Mein Nachname“ und da steht ausschließlich dein Nachname. Und Box #3? Die nennen wir jetzt „Mein Voller Name“. Eine praktische Eigenschaft von Variablen ist, dass wir mit ihnen rechnen können, also plus, minus, geteilt und so weiter. Das können wir hier anwenden, indem wir sagen der Inhalt von Box #3 = Box #1 + Box #2. Logisch, dein voller Name besteht aus deinem Vornamen und deinem Nachnamen.

1// Die Variable „meinVorname“ hat jetzt die Zuordnung „Caroline“
2let meinVorname = "Caroline";
3
4// Die Variable „meinNachname“ hat jetzt die Zuordnung „Müller“  
5let meinNachname = "Müller";
6
7// „meinVollerName“ hat jetzt die Zuordnung „Caroline Müller“
8let meinVollerName = meinVorname + " " + meinNachname;

In diesem Beispiel haben wir Buchstaben kombiniert, es geht aber selbstverständlich auch mit Zahlen. Als Beispiel könnten wir uns eine Formel zusammensetzen, um die Fläche eines Kreises zu berechnen:

1// Die Variable „radius“ hat den Wert 4 zugeordnet
2let radius = 4; 
3
4// Die Variable „pi“ hat den Wert 3.14 zugeordnet
5let pi = 3.14;
6
7/* Jetzt wird der Variablen „flaeche“ der Flächeninhalt eines Kreises
8ein Radius von 4 zugeordnet (ohne Einheit wie cm oder m) */
9let flaeche = radius*radius*pi;

Und wozu das jetzt alles? Es erspart dir viel Schreibarbeit, und wenn du irgendwelche Informationen mehrfach verwenden willst, kannst du überall bequem darauf zurückgreifen: Du schaust dir einfach den Inhalt der entsprechenden "Box" an. Um bei dem oberen Beispiel zu bleiben: wir würden gerne den Flächeninhalt eines Kreises mit dem Radius 73 wissen. Wir müssten nur die Variable „Radius“ neu zuordnen, der Rest bleibt gleich, sehr praktisch.

1// Die Variable „radius“ hat den Wert 4 zugeordnet
2let radius = 4; 
3
4//  Die Variable „pi“ hat den Wert 3.14 zugeordnet
5let pi = 3.14;
6
7/* Jetzt wird der Variablen „flaeche“ der Flächeninhalt eines Kreises
8ein Radius von 4 zugeordnet (ohne Einheit wie cm oder m) */
9let flaeche = radius*radius*pi;
10
11/* Die Variable „radius“ bekommt jetzt den größeren Wert 73, also hat
12auch die Variable "flaeche" nach der darauf folgenden Zuweisung einen
13größeren Wert */
14radius = 73;
15flaeche = radius*radius*pi;

Zusammenfassung:

  • Eine Variable ist ein veränderbarer Platzhalter, dem wir einen Namen geben

  • Wir können einer Variable einen Wert zuordnen (Zahlen oder Buchstaben) und diesen Wert auch später nochmal ändern

  • Man kann Variablen addieren, subtrahieren etc.

4 Verzweigungen

Eine weitere wichtige Grundlage ist die Verzweigung von Anweisungen, man könnte auch sagen die „logische Verknüpfung“ von Befehlen. Dafür stehen uns diverse „logische Operatoren“ zur Verfügung. Dabei setzt sich eine Verzweigung zusammen aus einer Bedingung, und das was passiert, wenn diese Bedingung erfüllt wurde. Ein einfaches Beispiel aus dem Alltag wird klarmachen was gemeint ist.

Du stehst an der Kasse im Supermarkt, du hast ein Eis mitgenommen und es wurde eingescannt und jetzt will man von dir 2,00 Euro. Jetzt gibt es im Grunde drei Möglichkeiten was passiert, die wir jetzt mal „durchspielen“ :

  1. Du hast zu wenig Geld dabei, dann kannst du das Eis nicht bezahlen und bekommst nichts.

  2. Du hast genau 2,00 Euro dabei, bezahlst und bekommst dafür das Eis.

  3. Du hast zu viel Geld dabei, z.B. einen 5er-Schein, bekommst also das Eis und 3,00 Euro Wechselgeld.

So könnte dieses Beispiel als Code aussehen:

1if(geldbeutel < 2.00) {
2   eis = 0;
3}
4
5/*Lass dich nicht verwirren, "==" ist kein Tippfehler,
6sondern vergleicht die beiden Werte 
7von "geldbeutel" und "2.00" */
8else if(geldbeutel == 2.00) { 
9   eis = 1; 
10   geldbeutel = 0;
11}
12else { 
13   eis = 1; 
14   geldbeutel = geldbeutel – 2.00; 
15}

Manche davon kennst du bereits aus der Schulmathematik, wie das Größer-Zeichen „>“ und das Kleiner-Zeichen „<“. Das Prüfen, ob beide Seiten den gleichen Wert haben, geschieht in den meisten Programmiersprachen mit "==". Im mittleren Beispiel bedeutet das: Wenn Geldbeutel einen Wert gleich 2,00 hat, dann passiert das, was in den geschweiften Klammern {} steht. Es gibt aber noch viele weitere logische Operatoren, die uns immer komplexere Verschachtelungen ermöglichen.

Zusammenfassung:

  • Wir können mithilfe von Verzweigungen die Variablen miteinander in Beziehungen stellen

  • Dafür gibt diverse logische Operatoren, mit denen wir vergleichen, verknüpfen etc.

  • Eine vollständige if-Verzweigung besteht in den meisten Programmiersprachen aus dem Schlüsselwort „if“, gefolgt von der Bedingung und dann das, was passiert, wenn die Bedingung erfüllt ist

5 Wiederholungen (Schleifen)

Jeder kennt sie, nervige Arbeiten bei denen wir stumpf immer wieder und wieder und wieder dasselbe machen müssen. Ein Beispiel aus dem Alltag wäre das Einräumen des Kühlschranks nach dem Einkaufen. Kühlschranktür auf, eine volle Einkaufstüte davor, wir greifen nach unten und holen etwas heraus, räumen es ein. Diesen Ablauf wiederholen wir einige Male. Wie oft wir das machen ist bei genauerer Überlegung ganz genau definiert, nämlich so oft bis eben alles im Kühlschrank eingeräumt ist.

Beim Programmieren nennt man das eine „Schleife“ oder auch „Wiederholung“. Das schöne ist, dass wir sie einmal programmieren, und die nervige Rechenarbeit liegt dann beim Computer. Dabei besteht eine Form der Schleife, die gezählte Wiederholung oder „for-Schleife“ aus genau drei Teilen:

  • ein Startwert,

  • eine Bedingung, wann die Schleife endet, und

  • eine Anweisung, wie sich die beiden Werte annähern, damit die Schleife eben endet.

Hier das Beispiel von oben.

1/* Unsere Einkaufstüte startet mit einem Inhalt von 14, z. B. Äpfeln;
2„einkaufstuete > 0“ sagt aus, dass die Schleifesolange wiederholt wird wie 
3der Inhalt unserer Tüte größer als 0 ist, logisch, denn dann ist sie leer; 
4„einkaufstuete = einkaufstuete - 1“ bedeutet, dass mit jedem mal, wenn wir 
5etwas auf der Tüte in den Kühlschrank legen, der Inhalt unserer Tüte um 1 
6reduziert */
7for (einkaufstuete = 14; einkaufstuete > 0; einkaufstuete = einkaufstuete - 1) { 
8/* Mit jedem Durchgang der Schleife wächst der Inhalt des Kühlschranks um 1, 
9sobald die Schleife fertig ist, gilt dementsprechend einkaufstuete = 0 und
10kuehlschrank = 14 */
11   kuehlschrank = kuehlschrank + 1; 
12}

Es gibt aber auch noch andere Formen für Schleifen, das ist teilweise eine Geschmacksfrage welche man lieber verwendet, generell ist die „for-Schleife“ wie oben aber nach etwas Eingewöhnungszeit die praktischste. Trotzdem dasselbe nochmal in Form einer „while-Schleife“:

1/* In dem hier gezeigten Beispiel ist diese Schreibform sicherlich auch 
2eine gute Wahl, schnell und übersichtlich, außerdem durch die Verwendung 
3der englischen Wörter einfach zu verstehen. Aber sobald die Algorithmen 
4verschachtelter werden, ist die „for-Schleife“ meistens übersichtlicher*/
5while (einkaufstuete > 0) {
6   einkaufstuete = einkaufstuete -1;
7   kuehlschrank = kuehlschrank + 1;
8}

Bei Wiederholungen besteht immer die Gefahr einer sogenannten Endlosschleife. Das ist eine Schleife, welche endlos wiederholt wird, weil die Bedingung zu ihrem Ende einfach nicht erfüllt wird. Hier ein kleines Beispiel:

1/* a hat hier immer einen Wert kleiner 0, dadurch wird diese Schleife 
2theoretisch endlos durchgeführt, und der Computer ordnet der Variable 
3"a" immer wieder „-5“ zu */
4a = -5;
5while(a < 0) {
6   a = -5; 
7}

Zusammenfassung:

  • Wir können mithilfe von Schleifen den Algorithmus eine Aufgabe mehrfach hintereinander bearbeiten lassen, ohne jede Wiederholung neu schreiben zu müssen

  • Dafür gibt es diverse Schreibweisen, je nach Anwendung kann die eine besser passen als die andere

  • Achten wir nicht auf Start- und Endbedingung der Schleife kann es sein, dass wir eine „Endlosschleife“ programmieren, die niemals aufhört, sich zu wiederholen

6 Arrays (Felder)

Bisher haben wir zum Speichern von Werten immer die Variablen genutzt, aber es gibt noch eine praktischere Methode. Vor allem wenn wir viele Werte haben, die thematisch miteinander zu tun haben. Dann sind sogenannte „Arrays“ oder auch Felder besonders zeitsparend.

Als Beispiel folgende Aufgabe: Wir sollen in deinem Wohnzimmer die Durchschnittstemperatur von einer ganzen Woche ermitteln. Ein Thermometer misst jede Stunde einmal. Das macht insgesamt 24 mal 7, also 168 Messungen über eine Woche. Für jede dieser Messungen extra eine Variable zu definieren, klingt nicht nur umständlich, das ist es auch. Stattdessen definieren wir uns ein Array namens „temperaturen“ in das wir die Werte speichern.

Man kann sich ein Array wie eine Liste vorstellen oder, vielleicht noch etwas bildlicher, wie eine Excel-Tabelle mit nur einer Spalte. Und genau wie die Zeilen einer Excel-Spalte, haben auch die einzelnen Bestandteile des Arrays hier jeweils einen sogenannte „Index“ (Mehrzahl„Indizes“), nur dass mit 0 angefangen wird zu zählen. Wollen wir also in unser Array „temperaturen“ die 168 Messungen speichern, wäre der letzte Index der Liste 167. Dieser Index wird in eckige Klammern hinter die Bezeichnung gesetzt. Hier als Beispiel bei unserer Temperaturmessung:

1// wir legen ein Array mit den Namen "temperaturen" an
2let temperaturen = [];
3
4//unsere erste Temperaturmessung hat den Wert 20 Grad
5temperaturen[0] = 20;  
6
7// auch die zweite Messung hat den Wert 20 Grad
8temperaturen[1] = 20;
9
10// die dritte Messung hat nun 22 Grad
11temperaturen[2] = 22;
12
13// ...
14
15// endlich am Ende angekommen, die letzte Messung hat 18 Grad ergeben
16temperaturen[167] = 18;

Und was kann man jetzt machen mit diesem Array? Mittels einer Schleife könnten wir den Computer beispielsweise die Summe aller 168 Messungen berechnen lassen, diese dann durch 168 teilen und schon haben wir unsere Durchschnittstemperatur. In der Praxis würde auch eine Schleife das Array mit den Messwerten füllen. Wenn man ein Array sinnvoll mit Informationen gefüllt hat, kann man verschiedenste Dinge daraus ermitteln. Wie oft hatten wir über die Woche 22 Grad im Wohnzimmer? Welche durchschnittliche Temperatur hatten wir jede Woche? Welche war die wärmste Woche, welche die kälteste?

Zusammenfassung:

  • Wir können mithilfe von Arrays größere Datenmengen sortieren und weiterverarbeiten

  • Dabei hat jedes Element des Arrays einen eindeutigen Index, die einzelnen Bestandteile des Arrays sind also durchnummeriert

  • Die Indexzählung beginnt jedoch bei 0! Haben wir ein Array planeten der Länge 8, ist der höchste Indexwert 7, also planeten[0] = "Merkur" und planeten[7] = "Neptun".

7 Funktionen

Im Kapitel „Variablen“ haben wir uns eine kleine Formel gebastelt, um die Fläche eines Kreises zu berechnen. So etwas ist mit etwas Übung ganz schnell passiert. Wir wissen, wenn wir die Fläche eines anderen Kreises brauchen, müssten wir nur den Wert der Variablen ändern. Wenn wir aber die Werte von zehn Kreise haben wollen oder die von 50? Man könnte natürlich den Code so oft wie man möchte untereinander kopieren. Das wäre aber nicht nur etwas nervig, sondern auch sehr schwer zu lesen. Und wenn man etwas ändern wollte, würde der Aufwand extrem groß werden. Deshalb erstellen wir uns lieber eine Vorlage für solche Fälle, eine sogenannte Funktion.

Dabei geben wir dieser Funktion, die wir programmieren, einen Namen und legen fest, welche Werte benutzt werden. Klingt kompliziert, aber anhand des Beispiels weiter unten wird es schnell klar.

1let pi = 3.14;
2 
3/* Das Schlüsselwort „function“ sagt dem Computer, dass 
4eine neue Funktion erstellt wird. Die hat hier den Namen 
5„kreisflaecheBerechnen“ und ihr wird als Zusatzinformation
6ein Radius übergeben, also eine Zahl: */
7function kreisflaecheBerechnen(radius) {
8
9/* Wir nutzen wieder die Formel für die Fläche eines Kreises.
10Hier taucht auch wieder der „radius“ von oben auf, denn dieser
11wird verwendet, um die Fläche zu berechnen */
12   let flaeche = radius*radius*pi;
13
14/* Der „return“-Befehl gibt das Ergebnis der Funktion zurück, 
15das heißt wir könnten diesen Wert für irgendetwas verwenden. 
16Beispielsweise könnten wir den Wert auf dem Bildschirm anzei- 
17gen lassen. */ 
18   return flaeche;
19}
20
21/* Die Funktion wird verwendet, um die Fläche verschiedener 
22Kreise zu berechnen. Die Zahl in der Klammer ist, wie oben 
23festgelegt, der Radius des Kreises: */
24kreisflaecheBerechnen(2); 
25kreisflaecheBerechnen(5);
26kreisflaecheBerechnen(6);

Umso öfter man irgendetwas wieder braucht, umso mehr lohnt es sich, so eine Funktion zu schreiben.

Zusammenfassung:

  • Eine Funktion ist eine von uns erstellte Vorlage für einen bestimmten Zweck

  • Wir können der Funktion Werte übergeben, damit diese beim Durchführen der Funktion benutzt werden können

8 Bibliotheken

So, fast geschafft. Jetzt zum Ende noch etwas Kurzes. Vielleicht hast du schon ein paar der unzähligen Tutorials im Internet angeschaut, die man zu den gängigen Programmiersprachen findet. Diese Frage hier wird da meist eher beiläufig erwähnt: Was sind Bibliotheken?

Vielleicht kennst du den Spruch „Man muss das Rad nicht neu erfinden“ und der ist hier sehr treffend. Man kann sich eine Bibliothek wie einen Werkzeugkasten vorstellen, darin sind bereits von anderen Leuten programmierte „Werkzeuge“, die wir nur noch verwenden müssen. Du hast deinen Hammer oder Schraubendreher zu Hause vermutlich auch nicht selbst gebaut, trotzdem kannst du sie verwenden, wenn du einmal gelernt hast wie. Wenn also in irgendeinem Tutorial etwas gesagt wird wie „...und dann noch diese Bibliothek hier einbinden…“ dann weißt du jetzt, dass es nur darum geht, bereits vorhandenen Code zu verwenden.

Beispielsweise irgendwelche Funktionen (die wir hier im Kurs bereits behandelt haben) welche nicht mehr selbst geschrieben werden müssen, sondern nur noch verwendet werden. Man findet auch zu eigentlich jeder Bibliothek ein „Handbuch“ (wird „Dokumentation“ genannt), in dem steht, welcher Befehl was macht.

Vielleicht fragst du dich jetzt : „Wo ist dann noch die Herausforderung dabei, wenn man bereits geschriebenen Code nur noch zusammensetzen muss?“

Es kann dir passieren, dass du mehrere Bibliotheken einfach zusammen verwendest, ohne dich vorher ein bisschen damit beschäftigt zu haben, was da im Hintergrund genau passiert. Das kann zu extrem merkwürdigen Fehlern führen, die sehr schwer zu finden sind. Wenn beispielsweise zwei Funktionen aus zwei Bibliotheken sich gegenseitig beeinflussen, ohne dass du das merkst.

Im Internet besteht eine kaum zählbare Anzahl von Bibliotheken. Und während manche absolut grandiose Hilfen darstellen, sind andere eher weniger brauchbar. Diese Qualitäten ziehen sich dann meist auch durch Bereiche wie die Dokumentation. Es gibt regelrechte „Klassiker“ unter den Bibliotheken für bestimmte Anwendungen, die sind dann häufig über viele Seiten perfekt dokumentiert und nachvollziehbar. Vorsicht also, wenn du einfach unvorsichtig irgendwelche Bibliotheken einbindest.

9 Schlusswort

Das waren jetzt viele Informationen auf einmal. Du hast irgendetwas nicht wirklich verstanden oder könntest eine Frage dazu nicht sofort beantworten? Völlig normal. Um bei dem Thema "Programmieren" weiterzukommen, führt kein Weg daran vorbei selbst ein bisschen rumzuprobieren. Dann werden manche Konzepte, die du hier kennengelernt hast, quasi "ganz von alleine" verständlich.

Hoffentlich hat der Kurs dir dennoch ein paar Fragen beantwortet oder zumindest das Interesse geweckt, noch mehr über das Thema zu lernen.


Dieses Werk steht unter der freien Lizenz
CC BY-SA 4.0Was bedeutet das?