Software Engineering an der Schule: Rekursive Datenstrukturen in neuem Gewand Dr. rer. nat. habil. Markus Steinert Peutinger-Gymnasium Augsburg Seminarlehrer Rekursion im Alltag / in der Kunst Dr. Markus Steinert Karlsruhe, 2011 2 Selbstähnliche Strukturen Eugen Jost Dr. Markus Steinert Karlsruhe, 2011 3 Rekursion in der Informatik Samuelson‘ sches Wirtschaftswachstum: Y0 , i0 Yi Y1 , i 1 a Y b Y c , i 1 i 2 i 1 Binomialkoeffizienten: Ackermannfunktion: let rec binomial n k = match k with | 0 -> 1 | k when (n=k) -> 1 | _ -> binomial (n-1) (k-1) + binomial (n-1) k;; A(0, n) = n + 1 A(m+1, 0) = A(m, 1) A(m+1, n+1) = A(m, A(m+1, n)) Dr. Markus Steinert Karlsruhe, 2011 4 Zentrale Frage Was macht Rekursion in formaler Schreibweise so schwierig, obwohl Visualisierungen auf den ersten (evtl. auch zweiten) Blick klar sind? • • Die Visualisierungen können als Instanziierungen konkreter Aufrufe der zugrunde liegenden rekursiven Vorschriften interpretiert werden Die funktionalen Repräsentationen sind die Vorschriften, mit denen derartige Strukturen erzeugt werden können Dr. Markus Steinert Karlsruhe, 2011 5 Klassische didaktische Strategien zur Einführung der Rekursion Rekursive Funktionen über (natürlichen) Zahlen: • • • Fakultätsfunktion Fibonacci – funktion Binomialkoeffizienten Didaktisch – motivatorische Probleme: • • • Für die Implementierung dieser Funktionen ist Rekursion nicht unbedingt notwendig; Sie können iterativ oft besser gelöst werden; Sie entstammen mathematischen Begrifflichkeiten: • • • Schüler: Wir machen Mathematik Brauchen wir überhaupt Informatik ? Schwache Schüler haben kein (korrektes) mentales Modell der Rekursion Dr. Markus Steinert Karlsruhe, 2011 6 Fehlerhafte Vorstellungen rekursiver Abläufe Sanders, et al. (2003 / 2006): Mental Models of recursion • Kategorisierung der Fehlvorstellungen • Empirische Untersuchungen (brauchbar / unbrauchbar) Dr. Markus Steinert Karlsruhe, 2011 7 Fehlerhafte Vorstellungen rekursiver Abläufe 1. Die häufigsten Fehlvorstellungen (Sanders et al.) • Schleifenartige Konzepte (Looping): Die rekursive Vorschrift wird schleifenartig immer wieder durchlaufen, d.h. - • Einschränkung auf Endrekursion (tail recursion); (Active): - • Rekursionen, bei denen nach Erreichen des Terminierungsfalls ein rückwärtiges Abarbeiten des Aufrufterms notwendig ist, werden nicht verstanden Wird auf kognitiver Ebene überhaupt ein Aufrufbaum realisiert? Einschränkung auf einmaliges Durchführen der Alternative (Step): - • es findet keine Instanziierung eines neuen Prozesses keine Generierung eines Aufrufbaums statt Die Alternative wird einmal ausgewertet und das „Ergebnis“ zurückgegeben Weitere Fehlvorstellungen: Magic, …. Dr. Markus Steinert Karlsruhe, 2011 8 Folgerungen aus den empirischen Arbeiten Wie hängen die Fehlvorstellungen mit den zu lernenden Konzepten zusammen? • • Die Lernenden können den Übergang vom rekursiven Algorithmus zum Aufrufbaum kognitiv nicht nachvollziehen bzw. bewältigen Die Lernenden hängen zu sehr an Ablaufmustern, wie sie aus dem „imperativen“ Programmierparadigma vertraut sind (Funktional vor Imperativ?) Folgerung: • • • Beim Erlernen rekursiver Abläufe sollte die Datenstruktur, die dabei traversiert wird, in den Vordergrund rücken Problem mit bisherigen Zugängen über Fibonacci-Funktion etc.: Die Traversierung ist zu trivial Alternative: Mit „weniger trivialen“ rekursiven Datenstrukturen beginnen! Dr. Markus Steinert Karlsruhe, 2011 9 Didaktik rekursiver Strukturen in der Literatur Velazquez – Iturbide (2000): • Gradual Steps: - • Argumentation: - • Recursion in Grammars, Recursion in Functional Programming, Recursion in Imperative Programming; Rekursiver Regeln in Grammatiken weisen einen minimalen syntaktischen Overhead auf und die Verbindung zur rekursiven Struktur ist denkbar einfach: S a | aS; zur Erzeugung der Sprache {an; n ≥ 1} Funktionale Sprachen im nächsten Schritt haben ebenfalls geringe syntaktische Anforderungen Problem: Für den Informatikunterricht weniger geeignet, da Grammatiken meist nur am Rande (bzw. sehr spät, z.B. im bayerischen Lehrplan erst in Jahrgangsstufe 12) und Funktionales Programmieren nicht thematisiert wird Dr. Markus Steinert Karlsruhe, 2011 10 Wo stehen wir? • • Offenbar werden graphische Repräsentationen rekursiver Strukturen intuitiv verstanden! Rekursive Algorithmen werden ohne Bezug auf die zugrunde liegende rekursive Struktur häufig nicht verstanden Folgerung: Wir sollten bei der Vermittlung von Rekursion von einem Modell der zugrunde liegenden rekursiven Strukturen ausgehen Dr. Markus Steinert Karlsruhe, 2011 11 Didaktische Rahmenbedingungen für das Unterrichten rekursiver Strukturen Lehrplan für den Informatikunterricht an bayerischen Gymnasien: • Rekursion als zentrale Thematik in der 11. Jahrgangsstufe • Vorwissen der Schüler • • • • Fundierte Kenntnisse im objektorientierten Modellieren: Objektdiagramme, Klassendiagramme, Sequenzdiagramme, Zustandssemantik Einschlägige Fertigkeiten beim Implementieren von objektorientierten Modellen (Aggregation, Assoziation, Vererbung, abstrakte Klassen, …) Einschlägige Fertigkeiten beim Implementieren imperativ konzipierter Abläufe Für das weitere wichtig: „Objects first!!“ • Vom Objektdiagramm zum Klassendiagramm Dr. Markus Steinert Karlsruhe, 2011 12 Didaktische Rahmenbedingungen für das Unterrichten rekursiver Strukturen im Detail Jahrgangsstufe 6 / 7: • Objekt- und Klassendiagramme hierarchischer Objektstrukturen Jahrgangstufe 10: • Nichtrekursive objektorientierte Programmierung (Felder, Referenzen, ….) Vererbung; abstrakte Klassen Jahrgangsstufe 11: 1. Konstruktion listen- / baumartiger Objektstrukturen 2. Das Kompositum als Schlüssel zur Rekursion 3. Rekursive Funktionen im Kompositum Realisierung im aktuellen Informatikunterricht: • • • Jahrgangsstufe 11, Informatik, an bayerischen Gymnasien Inzwischen im zweiten Durchlauf Erste Abiturprüfungen: Mai 2011 Dr. Markus Steinert Karlsruhe, 2011 13 Vom Objektdiagramm zum Klassendiagramm: Informatikunterricht in der Unterstufe (6. Jahrgangsstufe) Beispiel: Textstrukturen d1 : DOKUMENT a1 : ABSATZ z1 : ZEICHEN DOKUMENT Dr. Markus Steinert ……... enthält > a2 : ABSATZ z14 : ZEICHEN z15 : ZEICHEN ABSATZ Karlsruhe, 2011 a3 : ABSATZ … enthält > z55 : ZEICHEN … ZEICHEN 14 Vm Objekt- zum Klassendiagramm: Hierarchische Objektstrukturen DATEI Dr. Markus Steinert ORDNER Karlsruhe, 2011 enthält Objektorientierte Analyse von Ordnerstrukturen in Jahrgangsstufe 6 / 7 15 Was bedeutet diese Vorgehensweise aus lernzieltheoretischer Sicht? Werkzeug: Lernzielgraph 2: Objektorientiertes Modellieren 2 2 Textuell || Graphisch 1 3 Objekt 3 2 3 Graphisch 1 Aggregation auf Objektebene 3 Nichtrekursive Aggregation auf Klassenebene Graphisch 1 Baumartige Objektstrukturen Dr. Markus Steinert 3 Karlsruhe, 2011 Klasse Graphisch 1 2 2 3 2 Graphisch 1 Graphisch 1 Klassendiagramm baumartiger Objektstrukturen 16 Kurzes Zwischenresumè 1. Was wollten wir: • • Weg von einer Vorgehensweise, die zu falschen mentalen Modellen über Rekursion führt Probleme: Rekursive Aufrufe wurden nicht als Folge von Instanzen des jeweiligen Algorithmus verstanden 2. Was haben wir: • • • Wir modellieren zunächst baumartige Strukturen (Verzeichnisbäume etc.) Für diese rekursive Datenstruktur wird anschließend der „zugehörige Bauplan“, d.h. das Klassendiagramm konstruiert Das Klassendiagramm entspricht in diesem Bild der rekursiven Funktionsvorschrift 3. Wie geht es weiter: • • In der 10. Jahrgangsstufe lernen die Schüler das Implementieren (nichtrekursiver Klassenstrukturen In der 11. Jahrgangsstufe erfolgt der Übergang zu rekursiven Strukturen Dr. Markus Steinert Karlsruhe, 2011 17 1. Schritt: Listenartige Objektstrukturen (11. Jgstf.) Stativ1: STATIV erster Korb1: KNOTEN nächster Traube: ELEMENT STATIV erster Korb2: KNOTEN ELEMENT KNOTEN nächster Banane: ELEMENT 0, ..1 nächster Apfel: ELEMENT Korb3: KNOTEN nächster Entspricht dem aus der Unterstufe bekannten Modell! Dr. Markus Steinert Karlsruhe, 2011 18 1. Schritt: Konstruktion listenartiger Objektstrukturen (11. Jgstf.) class Knoten { private Element inhalt; private Knoten naechster; public Knoten(Element in) { inhalt = in; naechster = null; } Element inhalt1 = new Element(”Apfel”); // Erzeugen der Elemente Element inhalt2 = new Element(”Traube”); …….. Element inhalt3 = new Element(”Banane”); } Knoten korb1 = new Knoten(inhalt1, null); // Erzeugen der Knoten Knoten korb2 = new Knoten(inhalt2, null); Knoten korb3 = new Knoten(inhalt3, null); korb1.naechsterSetzen(korb2); // Aufbau der Liste korb2.naechsterSetzen(korb3); Listenkonstruktion: Zunächst explizit, ohne rekursive Ablaufmuster Traversierung: Zunächst Iterativ (Stativ enthält die Anzahl der Listenelemente) Dr. Markus Steinert Karlsruhe, 2011 19 Traversieren listenartiger Objektstrukturen (11. Jgstf.) Beispiel: Gesamtgewicht der Früchte in obiger Kette soll ermittelt werden! Stativ0 Knoten0 Knoten1 Knoten2 gesamtGewGeben() gewichtGeben() 0 kg + 5 kg 5 kg gewichtGeben() 5 kg + 6 kg 6 kg gewichtGeben() 11 kg + 4 kg 4 kg 15 kg Dr. Markus Steinert Karlsruhe, 2011 20 2. Schritt: Das Kompositum als Schlüssel zur Rekursion Problem: Abbruch bei Traversierung Stativ1: STATIV erster Apfel: ELEMENT STATIV Korb1: KNOTEN nächster Korb2: KNOTEN nächster ABSCHLUSS KNOTEN Banane: ELEMENT nächster Traube: ELEMENT LISTENELEMENT Korb3: KNOTEN ELEMENTnächster Kugel: ABSCHLUSS Dr. Markus Steinert Karlsruhe, 2011 21 3. Schritt: Rekursive Aufrufe (Sequenzdiagramm) Beispiel: Gesamtgewicht der Früchte in obiger Kette soll ermittelt werden! Stativ0 Knoten0 Knoten1 Abschluss0 Knoten2 gesamtGewGeben() gewichtGeben() gewichtGeben() gewichtGeben() gewichtGeben() 0 kg 4 kg 4 kg + 6 kg 15 kg Dr. Markus Steinert 10 kg + 5 kg Karlsruhe, 2011 22 Rekursive Funktionen im Kompositum: Summieren über bestimmte Eigenschaften abstract class Listenelement { } // Methoden des einzelnen Listenelementes public abstract Listenelement naechsterGeben(); class Knoten Listenelement { public abstractextends Element gewInhaltGeben(); private Listenelement naechster; Rekursiver Aufruf private Element inhalt; // rekursive Methoden der verketteten Liste public abstract int gewichtGeben(); public int gewichtGeben(){ public abstract Element inhaltLetzterGeben(Element aktuellerInhalt); return inhalt.gewInhaltGeben() + naechster.gewichtGeben(); public abstract Knoten hintenEinfuegen(Element knoteninhalt); } } …… class Abschluss extends Listenelement { public int gewichtGeben(){ return 0; } …… } Dr. Markus Steinert Karlsruhe, 2011 Terminierungsfall 23 Rekursive Funktionen im Kompositum: Letztes Element ausgeben abstract class Listenelement { class Knoten Listenelement { // Methoden des extends einzelnen Listenelementes Listenelement naechster; publicprivate abstract Listenelement naechsterGeben(); private Element inhalt; public abstract Element inhaltGeben(); Rekursiver Aufruf } …. Methoden der verketteten Liste // rekursive public abstract int anzahlKnotenGeben(); Element inhaltLetzterGeben(Element aktuellerInhalt){ public public abstract Element inhaltLetzterGeben(Element aktuellerInhalt); return naechster.inhaltLetzterGeben(inhalt); public abstract Knoten hintenEinfuegen(Element knoteninhalt); } class Abschluss extends Listenelement { …. …. } public Element inhaltLetzterGeben(Element aktuellerInhalt){ return aktuellerInhalt; } Terminierungsfall …. } Dr. Markus Steinert Karlsruhe, 2011 24 Vorteile der Strategie „Kompositum“ Lernzieltheoretisch lässt sich die Objektebene von der Klassenebene völlig trennen • Es können zunächst die Objektstrukturen und anschließend die „Konstruktionsvorschriften“, d.h. Klassendiagramme für diese Strukturen vermittelt werden • Der Weg vom Objekt- zum Klassenmodell lässt sich auch hier beschreiten Rekursive Methodenaufrufe lassen sich direkt auf dem Objektdiagramm ausführen und ergeben dabei in einfacher Weise den rekursiven Algorithmus • Terminierungsfall und rekursiver Aufruf verteilen sich auf die beiden Klassen ABSCHLUSS und KNOTEN • Die Ausführung eines rekursiven Methodenaufrufs lässt sich am Objektdiagramm / Sequenzdiagramm direkt illustrieren • Fehlvorstellungen (Sanders et al.) werden nach Möglichkeit vermieden Dr. Markus Steinert Karlsruhe, 2011 25 Lernzielgraph objektorientierter Modellierung von rekursiven Datenstrukturen Zusätzliche Modellierungskonzepte im Vergleich zur Unterstufe: • Spezifische Klassen (Abschluss, Knoten) • Verallgemeinerung der Beziehungen • Vererbung • Abstrakte Klassen (Programmierung: • Kontrollstrukturen • Umsetzung der Klassendiagramme in Quellcode) ) Dr. Markus Steinert Karlsruhe, 2011 26 Vergleich: Vorteile und Nachteile Vorteile: • • • • Der rekursive Aufruf ist stets an den Methodenaufruf eines anderen Objekts (hier: jeweils an das nächste Objekt) gekoppelt; Die Fehl-Vorstellung, es werde dieselbe Funktion aufgerufen, ist nahezu ausgeschlossen; Das mentale Modell der „Kopien“ wird automatisch vermittelt; Trennung von Terminierungsfall und rekursivem Aufruf, durch Auslagerung der Alternative in die Vererbung; Nachteile: • • Großer zeitlicher Aufwand; Umfangreiches Vorwissen und Fertigkeiten in objektorientierter Modellierung und Programmierung notwendig; Übertragung auf Grammatiken / funktionale Programmierung • • Definition rekursiver Grammatiken / Datenstrukturen Definition rekursiver Funktionen auf diesen Datenstrukturen Dr. Markus Steinert Karlsruhe, 2011 27 Einfügen eines Knotens am Ende der Liste: Leere Liste Das Stativ spricht zum Listenelement „erster“: „Erster, füge das Datenelement knoteninhalt hinten ein!“ und wartet auf die Beantwortung der Frage: „Wer ist mein neuer Erster?“ knoteninhalt erster class Liste { private Listenelement erster; } public void hintenEinfuegen(Datenelement knoteninhalt){ erster = erster.hintenEinfuegen(knoteninhalt); } ... ©S.Voss Dr. Markus Steinert Karlsruhe, 2011 28 Einfügen eines Knotens am Ende der Liste: Leere Liste „Wer ist mein neuer Erster?“ knoteninhalt Der Abschluss baut einen neuen Datenknoten, macht sich selbst zum Nachfolger dieses Datenknotens und legt den erhaltenen Inhalt knoteninhalt hinein. class Abschluss extends Listenelement { } public Datenknoten hintenEinfuegen(Datenelement knoteninhalt) { return new Datenknoten(this,knoteninhalt); } ... ©S.Voss Dr. Markus Steinert Karlsruhe, 2011 29 Einfügen eines Knotens am Ende der Liste: Leere Liste „Wer ist mein neuer Erster?“ knoteninhalt Der Abschluss antwortet seinem Fragesteller: Hier, nimm eine Referenz auf diesen neuen Datenknoten!“ class Abschluss extends Listenelement { } public Datenknoten hintenEinfuegen(Datenelement knoteninhalt) { return new Datenknoten(this,knoteninhalt); } ... ©S.Voss Dr. Markus Steinert Karlsruhe, 2011 30 Einfügen eines Knotens am Ende der Liste: Leere Liste Die Liste speichert nun die Referenz auf das erhaltene Listenelement in die Variable „erster“. erster class Liste { private Listenelement erster; } public void hintenEinfuegen(Datenelement knoteninhalt){ erster = erster.hintenEinfuegen(knoteninhalt); } ... ©S.Voss Dr. Markus Steinert Karlsruhe, 2011 31 Einfügen eines Knotens am Ende der Liste: Listenlänge > 1 Stativ spricht zum Listenelement „erster“: „Erster, füge das Datenelement knoteninhalt hinten ein!“ und wartet auf die Beantwortung der Frage: „Wer ist mein neuer Erster?“ knoteninhalt erster class Liste { private Listenelement erster; } public void hintenEinfuegen(Datenelement knoteninhalt){ erster = erster.hintenEinfuegen(knoteninhalt); } ... ©S.Voss Dr. Markus Steinert Karlsruhe, 2011 32 Einfügen eines Knotens am Ende der Liste: Listenlänge > 1 „Wer ist mein neuer Erster?“ Der Datenknoten spricht zum Listenelement „nächster“: „Nächster, füge das Datenelement knoteninhalt hinten ein! erster erster und wartet auf die Beantwortung der Frage: „Wer ist mein neuer Nächster?“ knoteninhalt class Datenknoten extends Listenelement { private Listenelement naechster; private Datenelement inhalt; nächster public Datenknoten hintenEinfuegen(Datenelement knoteninhalt){ naechster = naechster.hintenEinfuegen(knoteninhalt); return this; } ... } ©S.Voss Dr. Markus Steinert Karlsruhe, 2011 33 Einfügen eines Knotens am Ende der Liste: Listenlänge > 1 „Wer ist mein neuer Erster?“ „Wer ist mein neuer Nächster?“ erster erster Datenknoten spricht zum Listenelement „nächster“: „Nächster, füge das Datenelement knoteninhalt hinten ein!“ und wartet auf die Beantwortung der Frage: „Wer ist mein neuer Nächster?“ nächster class Datenknoten extends Listenelement { private Listenelement naechster; private Datenelement inhalt; } ©S.Voss public Datenknoten hintenEinfuegen(Datenelement knoteninhalt){ naechster = naechster.hintenEinfuegen(knoteninhalt); return this; } ... Dr. Markus Steinert Karlsruhe, 2011 nächster 34 Einfügen eines Knotens am Ende der Liste: Listenlänge > 1 „Wer ist mein neuer Erster?“ erster erster „Wer ist mein neuer Nächster?“ „Wer ist mein neuer Nächster?“ Der Abschluss baut einen neuen Datenknoten, macht sich selbst zum Nachfolger dieses Datenknotens und legt den erhaltenen Inhalt knoteninhalt hinein. nächster nächster class Abschluss extends Listenelement { } ©S.Voss public Datenknoten hintenEinfuegen(Datenelement knoteninhalt) { return new Datenknoten(this,knoteninhalt); } ... Dr. Markus Steinert Karlsruhe, 2011 35 Einfügen eines Knotens am Ende der Liste: Listenlänge > 1 „Wer ist mein neuer Erster?“ erster erster „Wer ist mein neuer Nächster?“ „Wer ist mein neuer Nächster?“ Der Abschluss antwortet seinem Fragesteller: Hier, nimm eine Referenz auf diesen neuen Datenknoten!“ nächster nächster class Abschluss extends Listenelement { } ©S.Voss public Datenknoten hintenEinfuegen(Datenelement knoteninhalt) { return new Datenknoten(this,knoteninhalt); } ... Dr. Markus Steinert Karlsruhe, 2011 36 Einfügen eines Knotens am Ende der Liste: Listenlänge > 1 erster erster „Wer ist mein neuer Erster?“ „Wer ist mein neuer Nächster?“ nächster Der Datenknoten speichert nun die Referenz auf das erhaltene Listenelement in die Variable „nächster“. und antwortet seinem Fragesteller: Hier, nimm eine Referenz auf mich selbst!“ nächster class Datenknoten extends Listenelement { private Listenelement naechster; private Datenelement inhalt; } ©S.Voss public Datenknoten hintenEinfuegen(Datenelement knoteninhalt){ naechster = naechster.hintenEinfuegen(knoteninhalt); return this; } ... Dr. Markus Steinert Karlsruhe, 2011 nächster 37 Einfügen eines Knotens am Ende der Liste: Listenlänge > 1 erster erster „Wer ist mein neuer Erster?“ Der Datenknoten speichert nun die Referenz auf das erhaltene Listenelement in die Variable „nächster“. und antwortet wiederum seinem Fragesteller: Hier, nimm eine Referenz auf mich selbst!“ nächster nächster class Datenknoten extends Listenelement { private Listenelement naechster; private Datenelement inhalt; } ©S.Voss public Datenknoten hintenEinfuegen(Datenelement knoteninhalt){ naechster = naechster.hintenEinfuegen(knoteninhalt); return this; } ... Dr. Markus Steinert Karlsruhe, 2011 nächster 38 Einfügen eines Knotens am Ende der Liste: Listenlänge > 1 erster erster Die Liste speichert nun die Referenz auf das erhaltene Listenelement in die Variable „erster“. nächster class Liste { private Listenelement erster; } nächster public void hintenEinfuegen(Datenelement knoteninhalt){ erster = erster.hintenEinfuegen(knoteninhalt); } ... nächster ©S.Voss Dr. Markus Steinert Karlsruhe, 2011 39 Einfügen eines Knotens am Ende der Liste: Sequenzdiagramm Dr. Markus Steinert Karlsruhe, 2011 40 Einfügen eines Knotens am Ende der Liste: Quellcode abstract class Listenelement { class Knoten Listenelement { // Methoden des extends einzelnen Listenelementes Listenelement naechster; publicprivate abstract Listenelement naechsterGeben(); private Element inhalt; public abstract Element inhaltGeben(); Rekursiver Aufruf } ….....Methoden der verketteten Liste // rekursive public abstract int anzahlKnotenGeben(); Knoten hintenEinfuegen(Element knoteninhalt) { publicpublic abstract Element inhaltLetzterGeben(Element aktuellerInhalt); naechster = naechster.hintenEinfuegen(knoteninhalt); public abstract Knoten hintenEinfuegen(Element knoteninhalt); return this; } class Abschluss extends Listenelement { } ……. public Knoten hintenEinfuegen(Element knoteninhalt) { return new Knoten (this, knoteninhalt); } Terminierungsfall } Dr. Markus Steinert Karlsruhe, 2011 41 Universelle Einsetzbarkeit: Warteschlange und Stapel Dr. Markus Steinert Karlsruhe, 2011 42 Universelle Einsetzbarkeit: Warteschlange und Stapel Dr. Markus Steinert Karlsruhe, 2011 43 Universelle Einsetzbarkeit: Warteschlange und Stapel Dr. Markus Steinert Karlsruhe, 2011 44 Universelle Einsetzbarkeit: Heterogene Listen Dr. Markus Steinert Karlsruhe, 2011 45 Universelle Einsetzbarkeit: Sortierte Listen einfügen(datenelement) wertEntnehmen(datenelement) ... < erster SORTIERTELISTE 1 sortiertEinfügen(datenelement) sortierwertEntnehmen(datenelement) ... ABSCHLUSS TELEFONEINTRAG DATENKNOTEN 1 name abteilung durchwahl DATENELEMENT istKleiner(datenelement) istGleich(datenelement) datenAusgeben() Dr. Markus Steinert 1 LISTENELEMENT istKleiner(datenelement) istGleich(datenelement) datenAusgeben() Karlsruhe, 2011 46 Von der rekursiven Liste zum binären Baum LISTE 1 LISTENELEMENT wurzel BAUMELEMENT 2 1 ABSCHLUSS DATENKNOTEN ABSCHLUSS 1 DATENELEMENT Dr. Markus Steinert < erster < 1 BINÄRBAUM Karlsruhe, 2011 DATENKNOTEN 1 DATENELEMENT 47 Von der rekursiven Liste zum binären Baum Dr. Markus Steinert Karlsruhe, 2011 48 Binäre Bäume: Traversierungsstrategien Preorder, Inorder, Postorder Dr. Markus Steinert Karlsruhe, 2011 49 Geordneter binäre Bäume: Suchen Dr. Markus Steinert Karlsruhe, 2011 50 Geordneter binäre Bäume: Suchen über Schlüssel Dr. Markus Steinert Karlsruhe, 2011 51 Geordneter binäre Bäume: Einfügen Dr. Markus Steinert Karlsruhe, 2011 52 Geordneter binäre Bäume: Einfügen Dr. Markus Steinert Karlsruhe, 2011 53 Vielen Dank Für Ihre Aufmerksamkeit Dr. Markus Steinert Karlsruhe, 2011 54