Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
faecher:informatik:oberstufe:adt:verkettete_liste:liste_java:start [20.10.2021 17:01] – sbel | faecher:informatik:oberstufe:adt:verkettete_liste:liste_java:start [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== Eine verkettete Liste mit Java ====== | ||
- | |||
- | ===== Definition: Verkettete Liste ===== | ||
- | |||
- | Eine (verkettete) **List** ist ein linearer abstrakter Datentyp mit den folgenden Methoden: | ||
- | |||
- | * Konstruktor '' | ||
- | * '' | ||
- | *'' | ||
- | * '' | ||
- | * '' | ||
- | * '' | ||
- | * '' | ||
- | * '' | ||
- | ===== Erarbeitung ===== | ||
- | |||
- | ==== Objektdiagramm ==== | ||
- | |||
- | Das **Objektdiagramm** einer Liste sieht folgendermaßen aus. | ||
- | |||
- | {{ : | ||
- | |||
- | Die Liste besteht aus verketteten Listenknoten (Objekt: **Node**), jeder Knoten hat (mindestens) zwei Attribute: Eine Referenz auf die mit dem Knoten gespeicherten Daten ('' | ||
- | |||
- | Die Listenklasse muss mindestens über ein Attribut '' | ||
- | |||
- | |||
- | ==== Implementationsdiagramm ==== | ||
- | |||
- | |||
- | {{ : | ||
- | |||
- | Hinweise: | ||
- | |||
- | * Liste und Knoten werden ist als generische Klassen implementiert und mit dem Typ-Parameter T parametrisiert, | ||
- | * Es gibt andere (komfortablere) Möglichkeiten Listen zu implementieren, | ||
- | |||
- | |||
- | |||
- | ==== Implementation ==== | ||
- | |||
- | Klone das Repo https:// | ||
- | |||
- | ---- | ||
- | {{: | ||
- | === (A1) Die Klasse '' | ||
- | |||
- | Die Klasse '' | ||
- | |||
- | ---- | ||
- | {{: | ||
- | === (A2) Konstruktor und die Methode '' | ||
- | |||
- | {{ : | ||
- | |||
- | Das Bild zeigt das Objektdiagramm einer leeren Liste. Füge der Klasse '' | ||
- | |||
- | ++++ Hilfe | | ||
- | Beantworte die folgenden Fragen und mache dir klar, was die Antworten für die Implementation des Konstruktors bedeuten: | ||
- | |||
- | * Benötigt der Konstruktor Parameter? | ||
- | * Welche Attribute hat das Listenobjekt? | ||
- | * Welche Anweisungen musst du deinem Konstruktor hinzufügen, | ||
- | |||
- | ++++ | ||
- | |||
- | Implementiere dann die Methode '' | ||
- | |||
- | Teste die Methode zunächst mit deiner leeren Liste. | ||
- | |||
- | ++++ Lösungsvorschlag | ||
- | <code java> | ||
- | [...] | ||
- | /** | ||
- | * Konstruktor | ||
- | | ||
- | */ | ||
- | public List() { | ||
- | this.first = null; | ||
- | } | ||
- | | ||
- | [...] | ||
- | | ||
- | /** | ||
- | * Gibt zurück, ob die Liste leer ist. | ||
- | * @return true, wenn die Liste keine Elemente enthält; false sonst | ||
- | */ | ||
- | public boolean isEmpty() { | ||
- | if (this.first == null ) { | ||
- | return true; | ||
- | } | ||
- | return false; | ||
- | } | ||
- | </ | ||
- | ++++ | ||
- | |||
- | |||
- | ---- | ||
- | {{: | ||
- | === (A3) Die Methode " | ||
- | |||
- | Beim Anhängen eines weiteren Knotens an die Liste sind zwei Fälle zu unterscheiden: | ||
- | - Die Liste ist leer | ||
- | - Die Liste ist nicht leer | ||
- | |||
- | **Liste leer** | ||
- | |||
- | Wenn die Liste Leer ist, ist der Vorgang schnell beschrieben, | ||
- | |||
- | * Erzeuge eine neuen Knoten mit dem Nachfolger " | ||
- | * Setze das Attribut first der Liste auf den neuen Knoten | ||
- | |||
- | {{ : | ||
- | |||
- | **(A)** Implementiere in der Methode '' | ||
- | |||
- | ---- | ||
- | **Liste nicht leer** | ||
- | |||
- | Das folgende Objektdiagramm veranschaulicht die Schritte, die beim Anhängen eines neuen Knotens an eine nicht leere Liste auszuführen sind. | ||
- | |||
- | {{ : | ||
- | |||
- | **(B)** Schreibe als Merksatz stichwortartig nieder, was beim Anhängen eines neuen Knotens alles passieren muss. | ||
- | |||
- | **Bewegen in der Liste** | ||
- | |||
- | Ein konkretes Problem stellt sich noch in Schritt 2 des Ablaufs zum Einfügen eines neuen Knotens: Wie können wir uns durch die Liste bewegen, wenn das Listenobjekt selbst nur die Referenz auf den ersten Knoten kennt? | ||
- | |||
- | Hier gehen wir ähnlich vor wie bei der Erhöhung einer Zählvariablen: | ||
- | ^Zähler ^ Liste ^ | ||
- | |<code java> | ||
- | // Neuer Zähler | ||
- | int i=0; | ||
- | // Zählen bis 99 | ||
- | while (i < 100) { | ||
- | i++; | ||
- | } | ||
- | // jetzt ist i 99 (nicht schön aber selten...) | ||
- | </ | ||
- | // Temporären Knotenzeiger mit dem Start der Liste initialisieren | ||
- | Node< | ||
- | // weitergehen bis zum Ende | ||
- | while(current.getNext()!= null) { | ||
- | current = current.getNext(); | ||
- | } | ||
- | // Jetzt zeigt current auf den letzten Knoten. | ||
- | |||
- | | | ||
- | |||
- | **(C)** Implementiere den zweiten Fall der Methode '' | ||
- | |||
- | ++++ Hilfe 1 zur Methode " | ||
- | |||
- | |||
- | |||
- | <code java> | ||
- | if (anfang == null) { | ||
- | // FIXME | ||
- | } else { | ||
- | // Durch die Knotenliste wandern. | ||
- | // dazu benötigt man den Startknoten und speichert sich den | ||
- | // in der Variablen k vom Typ Listenknoten< | ||
- | |||
- | | ||
- | |||
- | // k.nachfolger ist jetzt der nächste Knoten, | ||
- | // so kann man die Liste in einer while-Schleife | ||
- | // durchgehen... | ||
- | while ( // Bedingung für das ist nicht der letzte Knoten? ) { | ||
- | // k soll auf seinen Nachfolger gesetzt werden | ||
- | | ||
- | | ||
- | } | ||
- | </ | ||
- | |||
- | |||
- | ++++ | ||
- | |||
- | ++++ Hilfe 2 zur Methode " | ||
- | |||
- | <code java> | ||
- | // Um von einer Knoten zum nächsten zu gelangen, kann man den Ausdruck | ||
- | k = k.nachfolger; | ||
- | // verwenden. Das ersetzt den Knoten in der Variablen k durch seinen Nachfolger. | ||
- | |||
- | </ | ||
- | |||
- | ++++ | ||
- | |||
- | |||
- | ++++ Lösung zur Methode " | ||
- | |||
- | |||
- | <code java> | ||
- | if (anfang == null) { | ||
- | anfang = neu; | ||
- | } else { | ||
- | // Durch die Knotenliste wandern. | ||
- | // dazu benötigt man den Startknoten und speichert sich den | ||
- | // in der Variablen k vom Typ Listenknoten< | ||
- | |||
- | | ||
- | |||
- | // k.nachfolger ist jetzt der nächste Knoten, | ||
- | // so kann man die Liste in einer while-Schleife | ||
- | // durchgehen... | ||
- | while ( k.nachfolger != null ) { | ||
- | // k soll auf seinen Nachfolger setzen | ||
- | k = k.nachfolger; | ||
- | | ||
- | | ||
- | } | ||
- | </ | ||
- | |||
- | |||
- | ++++ | ||
- | |||
- | ---- | ||
- | {{: | ||
- | === (A2) Die weiteren Methoden | ||
- | |||
- | Die weiteren Methoden kannst du unter Zuhilfenahme der Kenntnisse aus Aufgabe 1 sicherlich gut implementieren - die Schlüsselstellen sind //"wie komme ich von einem Listenelement zum nächsten"// |