listen:verkettet:start
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
listen:verkettet:start [2024/09/18 07:55] – [Klassendiagramm] Martin Pabst | listen:verkettet:start [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== Warteschlange ====== | ||
- | <WRAP center round info 60%> | ||
- | Eine **Warteschlange** ist eine Liste, bei der Elemente **am Ende der Liste hinzugefügt** und **am Anfang entnommen** werden können. Man spricht vom **FIFO**-Prinzip: | ||
- | \\ \\ | ||
- | |||
- | //Denken Sie an eine Supermarktkasse: | ||
- | </ | ||
- | |||
- | ====== Implementierung als einfach verkettete Liste - erster Ansatz ====== | ||
- | <WRAP center round info 60%> | ||
- | Eine einfach verkettete Liste ist ein Ersatz für das Array um dessen Nachteile (Größenbeschränkung, | ||
- | Die Idee besteht darin, die Inhaltsobjekte hintereinanderzuhängen, | ||
- | {{ : | ||
- | |||
- | Beim letzten Inhaltsobjekt der Liste ist einfach '' | ||
- | |||
- | </ | ||
- | |||
- | ==== Als Java-Programm: | ||
- | < | ||
- | |||
- | <div class=" | ||
- | |||
- | <script type=" | ||
- | Supermarktkasse s = new Supermarktkasse(); | ||
- | s.hintenAnstellen(new Kunde(" | ||
- | s.hintenAnstellen(new Kunde(" | ||
- | s.hintenAnstellen(new Kunde(" | ||
- | s.hintenAnstellen(new Kunde(" | ||
- | |||
- | println(s.erstenEntnehmen().name); | ||
- | println(s.erstenEntnehmen().name); | ||
- | println(s.erstenEntnehmen().name); | ||
- | |||
- | |||
- | class Supermarktkasse { | ||
- | Kunde anfang; | ||
- | Kunde ende; | ||
- | |||
- | void hintenAnstellen(Kunde kunde) { | ||
- | if(anfang == null) { | ||
- | | ||
- | ende = kunde; | ||
- | | ||
- | } | ||
- | |||
- | ende.nachfolger = kunde; | ||
- | ende = kunde; | ||
- | |||
- | } | ||
- | |||
- | Kunde erstenEntnehmen() { | ||
- | Kunde erster = anfang; | ||
- | anfang = erster.nachfolger; | ||
- | return erster; | ||
- | } | ||
- | } | ||
- | |||
- | class Kunde { | ||
- | | ||
- | Kunde nachfolger; | ||
- | |||
- | | ||
- | this.name = name; | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | |||
- | </ | ||
- | |||
- | |||
- | <WRAP center round important 60%> | ||
- | **Problem 1: Vermischung von Struktur und Daten** \\ | ||
- | Bei dieser Implementierung der Warteschlange müssen wir die Klasse '' | ||
- | Der Kern des Problems liegt darin, dass der Code zur Modellierung der Daten (Klasse '' | ||
- | **Problem 2: Performance beim Zugriff aufs n-te Element** \\ | ||
- | Will man auf das n-te Element einer verketteten Liste zugreifen, so muss sich das Programm - beginnend beim ersten Element - n-mal "nach vorne hangeln" | ||
- | </ | ||
- | |||
- | |||
- | |||
- | ==== Klassendiagramm ==== | ||
- | <WRAP center round info 60%> | ||
- | {{ : | ||
- | Es ergibt sich das rechts dargestellte Klassendiagramm. \\ \\ | ||
- | Die einfach verkettete Liste ist eine **rekursive** Datenstruktur. Dabei weist **rekursiv** (lat. recurrere „zurücklaufen“) darauf hin, dass ein Kunde-Objekt wiederum ein Kunde-Objekt als Nachfolger hat. | ||
- | Zwischen den Klassen Warteschlange und Kunde bestehen zwei **Aggregationsbeziehungen**. | ||
- | </ | ||
- | |||
- | ===== Umsetzung in Java ===== | ||
- | Sehen wir uns zunächst nur die Klassen und ihre Attribute an: | ||
- | <code learnj> | ||
- | class Inhalt { | ||
- | | ||
- | | ||
- | |||
- | | ||
- | this.text = text; | ||
- | } | ||
- | |||
- | | ||
- | return nachfolger; | ||
- | } | ||
- | |||
- | | ||
- | println(text); | ||
- | } | ||
- | | ||
- | } | ||
- | |||
- | class Warteschlange { | ||
- | |||
- | | ||
- | |||
- | | ||
- | erster = null; | ||
- | } | ||
- | |||
- | } | ||
- | |||
- | |||
- | </ | ||
- | |||
- | Die Methode '' | ||
- | |||
- | <code learnj> | ||
- | public Inhalt erstenEntnehmen() { | ||
- | |||
- | Inhalt z = erster; | ||
- | | ||
- | if(erster == null) { | ||
- | | ||
- | } | ||
- | |||
- | erster = erster.getNachfolger(); | ||
- | |||
- | return z; | ||
- | |||
- | } | ||
- | </ | ||
- | |||
- | 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 rekursive Lösung ist zweigeteilt. Der einfachste Fall (die Liste ist leer) wird direkt in der Klasse Warteschlange behandelt (es wird '' | ||
- | |||
- | **Klasse Warteschlange: | ||
- | <code learnj> | ||
- | public void hintenAnstellenRekursiv(Inhalt inhalt) { | ||
- | | ||
- | erster = inhalt; | ||
- | } else { | ||
- | erster.hintenAnstellenRekursiv(inhalt); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | **Klasse Inhalt:** | ||
- | <code learnj> | ||
- | public void hintenAnstellenRekursiv(Inhalt inhalt) { | ||
- | | ||
- | nachfolger = inhalt; | ||
- | } else { | ||
- | nachfolger.hintenAnstellenRekursiv(inhalt); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | Auch die Ermittlung der Anzahl der enthaltenen Elemente kann sowohl iterativ als auch rekursiv gelöst werden. [[datenstrukturen: | ||
- | |||
- | ==== Anzahl der enthaltenen Elemente: rekursiv ==== | ||
- | Hier kümmert sich die Methode '' | ||
- | === Klasse Warteschlange: | ||
- | <code learnj> | ||
- | public int getAnzahlRekursiv() { | ||
- | | ||
- | return 0; | ||
- | } else { | ||
- | return erster.getAnzahlRekursiv(); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | === Klasse Inhalt: === | ||
- | <code learnj> | ||
- | /** | ||
- | * Gibt die Anzahl der Elemente " | ||
- | * zzgl. 1 zurück; | ||
- | */ | ||
- | public int getAnzahlRekursiv() { | ||
- | | ||
- | return 1; | ||
- | } else { | ||
- | return nachfolger.getAnzahlRekursiv() + 1; | ||
- | } | ||
- | |||
- | } | ||
- | </ | ||
- | |||
- | ===== 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 { | ||
- | |||
- | | ||
- | |||
- | | ||
- | erster = null; | ||
- | } | ||
- | |||
- | | ||
- | if(erster == null) { | ||
- | | ||
- | } else { | ||
- | | ||
- | } | ||
- | } | ||
- | |||
- | | ||
- | | ||
- | Inhalt z = erster; | ||
- | |||
- | erster = erster.getNachfolger(); | ||
- | |||
- | return z; | ||
- | |||
- | } | ||
- | |||
- | | ||
- | if(erster == null) { | ||
- | | ||
- | } else { | ||
- | | ||
- | } | ||
- | } | ||
- | |||
- | } | ||
- | </ | ||
- | |||
- | <script type=" | ||
- | class Inhalt { | ||
- | | ||
- | | ||
- | |||
- | | ||
- | this.text = text; | ||
- | } | ||
- | |||
- | /** | ||
- | * Gibt die Anzahl der Elemente " | ||
- | * zzgl. 1 zurück; | ||
- | */ | ||
- | | ||
- | if(nachfolger == null) { | ||
- | | ||
- | } else { | ||
- | | ||
- | } | ||
- | |||
- | } | ||
- | |||
- | | ||
- | return nachfolger; | ||
- | } | ||
- | |||
- | | ||
- | if(nachfolger == null) { | ||
- | | ||
- | } else { | ||
- | | ||
- | } | ||
- | } | ||
- | |||
- | |||
- | | ||
- | println(text); | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | |||
- | </ | ||
- | |||
- | </ | ||
listen/verkettet/start.1726646132.txt.gz · Zuletzt geändert: 2024/09/22 04:37 (Externe Bearbeitung)