listen:trennungstrukturdaten:start
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
listen:trennungstrukturdaten:start [2024/09/19 07:15] – Martin Pabst | listen:trennungstrukturdaten:start [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== Trennung von Struktur und Daten ====== | ||
- | <WRAP center round info 80%> | ||
- | Im [[listen: | ||
- | |||
- | Die Lösungsidee besteht darin, jedes Datenobjekt in ein Objekt einer neuen Klasse '' | ||
- | </ | ||
- | |||
- | ==== Beispielhaftes Objektdiagramm ==== | ||
- | {{ : | ||
- | ==== Klassendiagramm ==== | ||
- | {{ : | ||
- | |||
- | ===== Umsetzung in Java ===== | ||
- | === Die Klasse Inhalt === | ||
- | Die Klasse '' | ||
- | <code learnj> | ||
- | class Kunde { | ||
- | | ||
- | |||
- | | ||
- | this.name = name; | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Sehen wir uns bei den Klassen '' | ||
- | <code learnj> | ||
- | public class Warteschlange { | ||
- | private Knoten erster; | ||
- | | ||
- | } | ||
- | |||
- | public class Knoten { | ||
- | private Knoten nachfolger; | ||
- | private Inhalt inhalt; | ||
- | | ||
- | public Knoten(Inhalt inhalt){ | ||
- | | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Die Klasse '' | ||
- | Die Warteschlange setzt damit das Prinzip der **Trennung von Struktur und Inhalt** um, d.h. bei der Verwendung der Struktur (hier: Warteschlange bzw. Liste) sind keinerlei Änderungen an der Klasse '' | ||
- | |||
- | Damit die Warteschlange auf die Knoten geeignet zugreifen kann, benötigt die Klasse '' | ||
- | <code learnj> | ||
- | | ||
- | return nachfolger; | ||
- | } | ||
- | |||
- | void setNachfolger(Knoten nachfolger) { | ||
- | this.nachfolger = nachfolger; | ||
- | } | ||
- | |||
- | Kunde getDaten() { | ||
- | return daten; | ||
- | } | ||
- | </ | ||
- | |||
- | Die Methode '' | ||
- | |||
- | <code learnj> | ||
- | Kunde erstenEntnehmen() { | ||
- | Knoten erster = anfang; | ||
- | anfang = erster.getNachfolger(); | ||
- | return erster.getDaten(); | ||
- | } | ||
- | </ | ||
- | |||
- | Kaum schwerer ist das Anfügen neuer Knoten am Ende der Warteschlange: | ||
- | <code learnj> | ||
- | void hintenAnstellen(Kunde kunde) { | ||
- | if(anfang == null) { | ||
- | | ||
- | ende = anfang; | ||
- | | ||
- | } | ||
- | |||
- | Knoten neuerKnoten = new Knoten(kunde); | ||
- | ende.setNachfolger(neuerKnoten); | ||
- | ende = neuerKnoten; | ||
- | |||
- | } | ||
- | </ | ||
- | |||
- | Schwieriger gestaltet sich das Einfügen des letzten Knotens, da das Warteschlangen-Objekt ja nur die Referenz auf den ersten Knoten speichert und man sich von diesem ausgehend zum letzten Knoten " | ||
- | |||
- | ==== Hintenanstellen: | ||
- | Die iterative Lösung " | ||
- | <code learnj> | ||
- | public void hintenAnstellenIterativ(Inhalt inhalt) { | ||
- | if(erster == null) { | ||
- | erster = new Knoten(inhalt); | ||
- | } else { | ||
- | Knoten aktuellerKnoten = erster; | ||
- | while(aktuellerKnoten.getNachfolger() != null) { | ||
- | aktuellerKnoten = aktuellerKnoten.getNachfolger(); | ||
- | } | ||
- | aktuellerKnoten.setNachfolger(new Knoten(inhalt)); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Hintenanstellen: | ||
- | Die rekursive Lösung ist zweigeteilt. Der einfachste Fall (die Liste ist leer) wird direkt in der Klasse Warteschlange behandelt (es wird ein neuer Knoten erzeugt und als erster Knoten eingesetzt). Die " | ||
- | |||
- | **Klasse Warteschlange: | ||
- | <code learnj> | ||
- | public void hintenAnstellenRekursiv(Inhalt inhalt) { | ||
- | if(erster == null) { | ||
- | erster = new Knoten(inhalt); | ||
- | } else { | ||
- | erster.hintenAnstellenRekursiv(inhalt); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | **Klasse Knoten:** | ||
- | <code learnj> | ||
- | public void hintenAnstellenRekursiv(Inhalt inhalt) { | ||
- | if(nachfolger == null) { | ||
- | nachfolger = new Knoten(inhalt); | ||
- | } else { | ||
- | nachfolger.hintenAnstellenRekursiv(inhalt); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Auch die Ermittlung der Anzahl der enthaltenen Elemente kann sowohl iterativ als auch rekursiv gelöst werden: | ||
- | |||
- | ==== Anzahl der enthaltenen Elemente: iterativ ==== | ||
- | **Klasse Warteschlange: | ||
- | <code learnj> | ||
- | public int getAnzahlIterativ() { | ||
- | | ||
- | return 0; | ||
- | } | ||
- | |||
- | int anzahl = 1; | ||
- | | ||
- | | ||
- | aktuellerKnoten = aktuellerKnoten.getNachfolger(); | ||
- | anzahl++; | ||
- | } | ||
- | |||
- | | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Anzahl der enthaltenen Elemente: rekursiv ==== | ||
- | Hier kümmert sich die Methode '' | ||
- | **Klasse Warteschlange: | ||
- | <code learnj> | ||
- | public int getAnzahlRekursiv() { | ||
- | | ||
- | return 1; | ||
- | } | ||
- | |||
- | | ||
- | } | ||
- | </ | ||
- | |||
- | ==== Sequenzdiagramm am Beispiel einer Warteschlange mit drei Knoten: ==== | ||
- | {{ : | ||
- | ===== Gesamtprogramm ===== | ||
- | < | ||
- | |||
- | <div class=" | ||
- | |||
- | <script type=" | ||
- | Warteschlange w = new Warteschlange(); | ||
- | w.hintenAnstellenRekursiv(new Inhalt(" | ||
- | w.hintenAnstellenRekursiv(new Inhalt(" | ||
- | w.hintenAnstellenRekursiv(new Inhalt(" | ||
- | |||
- | println(" | ||
- | |||
- | Inhalt inhalt = w.erstenEntnehmen(); | ||
- | inhalt.ausgabe(); | ||
- | inhalt = w.erstenEntnehmen(); | ||
- | inhalt.ausgabe(); | ||
- | </ | ||
- | |||
- | <script type=" | ||
- | class Warteschlange { | ||
- | | ||
- | |||
- | | ||
- | if(erster == null) { | ||
- | | ||
- | } else { | ||
- | | ||
- | | ||
- | aktuellerKnoten = aktuellerKnoten.getNachfolger(); | ||
- | } | ||
- | | ||
- | } | ||
- | } | ||
- | |||
- | | ||
- | if(erster == null) { | ||
- | | ||
- | } else { | ||
- | | ||
- | } | ||
- | } | ||
- | |||
- | | ||
- | if(erster == null) { | ||
- | | ||
- | } | ||
- | | ||
- | int anzahl = 1; | ||
- | Knoten aktuellerKnoten = erster; | ||
- | while(aktuellerKnoten.getNachfolger() != null) { | ||
- | | ||
- | | ||
- | } | ||
- | |||
- | return anzahl; | ||
- | } | ||
- | |||
- | | ||
- | if(erster == null) { | ||
- | | ||
- | } | ||
- | return erster.getAnzahlRekursiv(); | ||
- | } | ||
- | |||
- | | ||
- | if(erster == null) { | ||
- | | ||
- | } | ||
- | | ||
- | Inhalt inhalt = erster.getInhalt(); | ||
- | erster = erster.getNachfolger(); | ||
- | | ||
- | return inhalt; | ||
- | } | ||
- | |||
- | } | ||
- | </ | ||
- | |||
- | <script type=" | ||
- | class Knoten { | ||
- | | ||
- | | ||
- | |||
- | | ||
- | this.inhalt = inhalt; | ||
- | } | ||
- | |||
- | | ||
- | return inhalt; | ||
- | } | ||
- | |||
- | | ||
- | return nachfolger; | ||
- | } | ||
- | |||
- | | ||
- | this.nachfolger = nachfolger; | ||
- | } | ||
- | |||
- | | ||
- | if(nachfolger == null) { | ||
- | | ||
- | } else { | ||
- | | ||
- | } | ||
- | } | ||
- | |||
- | | ||
- | if(nachfolger == null) { | ||
- | | ||
- | } | ||
- | |||
- | return nachfolger.getAnzahlRekursiv() + 1; | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | <script type=" | ||
- | // Dies ist nur eine beispielhafte Inhalt-Klasse. Ihre Attribute und Methoden sind nicht relevant | ||
- | // für das Funktionieren der einfach-verketteten Liste, d.h. Struktur und Inhalt sind sauber getrennt! | ||
- | |||
- | class Inhalt { | ||
- | | ||
- | | ||
- | this.text = text; | ||
- | } | ||
- | | ||
- | println(text); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | </ | ||
- | |||
- | </ | ||
- | |||
- | <WRAP center round todo 60%> | ||
- | **Aufgabe 1:** \\ \\ | ||
- | Erweitere die Klasse Warteschlange um eine Methode '' | ||
- | [[.ntesElementLoesung: | ||
- | **Aufgabe 2:** \\ \\ | ||
- | Erweitere die Klasse Warteschlange um eine Methode '' | ||
- | [[.letztesLoeschenLoesung: | ||
- | </ | ||
- | |||
listen/trennungstrukturdaten/start.1726730116.txt.gz · Zuletzt geändert: 2024/09/22 04:37 (Externe Bearbeitung)