Erste Schritte Verkettete Liste rekursiv umprogrammieren

Khaotix

Mitglied
Hey :)

Meine Aufgabe besteht darin eine verkettete Liste rekursiv zu programmieren.

Dazu erst einmal die Klasse "VerketteteListe", unten ist dazu die Klasse "Listeknoten"

KLASSE VERKETTETELISTE
Code:
public class VerketteteListe {

  /**
  * Erster Knoten in der Liste der verketteten Knoten.
  */
  private Listenknoten listenkopf;

  /**
  * Erzeugt eine leere Liste.
  */
  public VerketteteListe() {

  this.listenkopf = null;
  }

KLASSE LISTENKNOTEN
Code:
public class Listenknoten {

  /**
  * Inhalt dieses Knotens.
  */
  private String inhalt;

  /**
  * Nachfolgender Listenknoten.
  */
  private Listenknoten nachfolger;


 
  public Listenknoten(String inhalt) {

  this.inhalt = inhalt;
  this.nachfolger = null;
  }

  /**
  * Erzeugt einen neuen Listenknoten mit der übergebenen
  * Zeichenkette als Inhalt und dem übergebenen Knoten
  * als Nachfolger.
  */
  public Listenknoten(String inhalt, Listenknoten nachfolger) {

  this.inhalt = inhalt;
  this.nachfolger = nachfolger;
  }

  /**
  * Liefert den Inhalt dieses Listenknotens.
  */
  public String gibInhalt() {

  return this.inhalt;
  }

  /**
  * Liefert den nachfolgenden Listenknoten.
  */
  public Listenknoten gibNachfolger() {

  return this.nachfolger;
  }

  /**
  * Weist diesem Listenknoten einen neuen Nachfolger zu.
  */
  public void setzeNachfolger(Listenknoten knoten) {

  this.nachfolger = knoten;
  }
}

Ich soll hierbei die Methoden void entferne(int position) und void fuegeHinzu(int position,String inhalt) programmieren.
"Entferne" soll dabei das Element an gewählter Stelle entfernen.
"FuegeHinzu" soll ein Element an gewählter Stelle hinzufügen.

In der Aufgabe steht auch, das etwas in der Klasse Listenknoten geändert werden müsse, damit es funktioniert.

Wie bereits gesagt, muss das Ganze Rekursiv programmiert werden.

Ich bitte hierbei um ein Paar Tipps, da ich nicht darauf komme, was ich in der Klasse Listenknoten ändern soll, bzw. wie das ganze funktionieren soll.


Vielen Dank bereits im Vorraus.
 

Khaotix

Mitglied
Hier die Aufgabenstellung.

Aufgabenstellung:

Gehen Sie für diese Aufgabe von den Klassen VerketteteListe und Listenknoten aus der Vorlesung aus, wobei wir jedoch annehmen, dass die Klasse VerketteteListe nur die Instanzvariable listenkopf besitzt.
Stellen Sie die Realisierungen der Methoden void entferne(int) und void fuegeHinzu(int, String) aus der Klasse VerketteteListe auf Rekursion um. Hierzu müssen Sie auch in der Klasse Listenknoten Änderungen vornehmen.

Und nochmal damit alles auch komplett ist, die Methoden.

Java:
/**
  * Fügt eine Zeichenkette an der angegebenen Position
  * in diese Liste ein.
  *
  * @param position  Position, an der die Zeichenkette eingefügt
  *  wird. Wenn position == 0, wird vorne eingefügt.
  *  Wenn position == 1, wird an zweiter Stelle eingefügt usw.
  * @param inhalt  Zeichenkette, die hinzugefügt wird
  */
  public void fuegeHinzu(int position, String inhalt) {

  if (position == 0) {
  fuegeVorneHinzu(inhalt);
  } else if (position == this.listenlaenge) {
  fuegeHintenHinzu(inhalt);
  } else if ((position > 0) && (position < this.listenlaenge)) {

  Listenknoten knoten = new Listenknoten(inhalt);

  /* Der neue Knoten muss hinter dem Knoten an Position position - 1
  * eingefügt werden. Deshalb die Liste durchlaufen, bis Variable
  * k den Knoten an dieser Position enthält.
  */
  Listenknoten vorgaenger = this.listenkopf;
  for (int i = 1; i < position; i = i + 1) {
  vorgaenger = vorgaenger.gibNachfolger();
  }

  /* Neuen Knoten als Nachfolger des Knotens an Position
  * position - 1 (Wert der Variablen vorgaenger) einfügen.
  */
  knoten.setzeNachfolger(vorgaenger.gibNachfolger());
  vorgaenger.setzeNachfolger(knoten);

  this.listenlaenge = this.listenlaenge + 1;
  }
  }

public void entferne(int index) {

  if ((index >= 0) && (index < this.listenlaenge)) {

  if (index == 0) {

  /* Die Liste ist nicht leer und es soll der erste Knoten
  * entfernt werden.
  */
  this.listenkopf = this.listenkopf.gibNachfolger();

  /* Enthielt die Liste zuvor nur einen Knoten, so ist
  * anschließend auch das Listenende die null-Referenz.
  */
  if (this.listenkopf == null) {
  this.listenende = null;
  }

  this.listenlaenge = this.listenlaenge - 1;

  } else {

  /* Die Liste ist nicht leer und es wird ein mittlerer
  * oder der letzte Knoten entfernt.
  */

  /* Durch die Liste laufen, sodass anschließend aktuellerKnoten
  * den Knoten enthält, der entfernt werden soll, und
  * vorherigerKnoten seinen Vorgänger.
  */
  Listenknoten aktuellerKnoten = this.listenkopf;
  Listenknoten vorherigerKnoten = null;
  for (int i = 1; i <= index; i = i + 1) {
  vorherigerKnoten = aktuellerKnoten;
  aktuellerKnoten = aktuellerKnoten.gibNachfolger();
  }

  /* Der Knoten wird entfernt, indem sein Nachfolger zum
  * Nachfolger des Vorgängers wird.
  */
  vorherigerKnoten.setzeNachfolger(
  aktuellerKnoten.gibNachfolger());

  /* Wurde der letzte Knoten entfernt, muss das Listenende
  * aktualisiert werden.
  */
  if (vorherigerKnoten.gibNachfolger() == null) {
  this.listenende = vorherigerKnoten;
  }

  this.listenlaenge = this.listenlaenge - 1;
  }
  }
  }
 
Zuletzt bearbeitet von einem Moderator:

Khaotix

Mitglied
Oh tut mir Leid. Ich habe aus Versehen die Klassen gepostet, die ich bereits ein Wenig geändert habe. Hier nochmal die kompletten unbearbeiteten Klassen.

Code:
/**
 * Ein Objekt dieser Klasse repräsentiert eine einfach
 * verkettete Liste von Zeichenketten.
 */
public class VerketteteListe {

 
  private Listenknoten listenkopf;

  
  private Listenknoten listenende;

  private int listenlaenge;

  public VerketteteListe() {

  this.listenkopf = null;
  this.listenende = null;
  this.listenlaenge = 0;
  }

  /**
  * Fügt eine Zeichenkette vorne in dieser Liste hinzu.
  */
  public void fuegeVorneHinzu(String inhalt) {

  this.listenkopf = new Listenknoten(inhalt, this.listenkopf);

  if (this.listenende == null) {


  this.listenende = this.listenkopf;
  }

  this.listenlaenge = this.listenlaenge + 1;
  }

  /**
  * Fügt eine Zeichenkette hinten in dieser Liste hinzu.
  */
  public void fuegeHintenHinzu(String inhalt) {

  if (this.listenkopf == null) {

 
  this.listenkopf = new Listenknoten(inhalt);
  this.listenende = this.listenkopf;

  } else {

 
  Listenknoten knoten = new Listenknoten(inhalt);
  this.listenende.setzeNachfolger(knoten);
  this.listenende = knoten;
  }

  this.listenlaenge = this.listenlaenge + 1;
  }

  /**
  * Fügt eine Zeichenkette an der angegebenen Position
  * in diese Liste ein.
  *
  */
  public void fuegeHinzu(int position, String inhalt) {

  if (position == 0) {
  fuegeVorneHinzu(inhalt);
  } else if (position == this.listenlaenge) {
  fuegeHintenHinzu(inhalt);
  } else if ((position > 0) && (position < this.listenlaenge)) {

  Listenknoten knoten = new Listenknoten(inhalt);


  Listenknoten vorgaenger = this.listenkopf;
  for (int i = 1; i < position; i = i + 1) {
  vorgaenger = vorgaenger.gibNachfolger();
  }

  /* Neuen Knoten als Nachfolger des Knotens an Position
  * position - 1 (Wert der Variablen vorgaenger) einfügen.
  */
  knoten.setzeNachfolger(vorgaenger.gibNachfolger());
  vorgaenger.setzeNachfolger(knoten);

  this.listenlaenge = this.listenlaenge + 1;
  }
  }

  /**
  * Fügt eine Zeichenkette an der angegebenen Position
  * in diese Liste ein.
  */
  public void fuegeHinzuOhneListenlaenge(int position, String inhalt) {

  if (position == 0) {

  /* Knoten wird vorne hinzugefügt.
  */
  this.listenkopf = new Listenknoten(inhalt, this.listenkopf);

  if (this.listenende == null) {

  
  this.listenende = this.listenkopf;
  }

  this.listenlaenge = this.listenlaenge + 1;

  } else {

  /* Knoten soll nicht vorne hinzugefügt werden.
  */

  /* Zähler zur Ermittlung der Einfügeposition.
  */
  int positionszaehler = 1;

  Listenknoten vorgaenger = this.listenkopf;


  while ((positionszaehler < position) && (vorgaenger != null)) {
  positionszaehler = positionszaehler + 1;
  vorgaenger = vorgaenger.gibNachfolger();
  }

  /* Falls vorgaenger == null, so ist die Einfügeposition
  * für diese Liste ungültig.
  */

  if (vorgaenger != null) {


  Listenknoten knoten =
  new Listenknoten(inhalt, vorgaenger.gibNachfolger());
  vorgaenger.setzeNachfolger(knoten);
  this.listenlaenge = this.listenlaenge + 1;

  /* Ist der neue Knoten der letzte der Liste, muss das
  * Listenende gesetzt werden.
  */
  if (knoten.gibNachfolger() == null) {
  this.listenende = knoten;
  }
  }
  }
  }

  
  public void fuegeSortiertHinzu(String inhalt) {

  /* Hier wird zu Zwecken der Anschauung eine Implementierung
  * gewählt, in der von den Methoden fuegeVorneHinzu und
  * fuegeHintenHinzu kein Gebrauch gemacht wird.
  */

  Listenknoten knoten = new Listenknoten(inhalt);

  if (this.listenkopf == null) {

  /* Die Liste ist leer. Neuer Knoten wird Listenkopf und Listenende.
  */
  this.listenkopf = knoten;
  this.listenende = this.listenkopf;

  } else {

  /* Die Liste ist nicht leer.
  */

  /* Liste vom Listenkopf an solange durchlaufen, bis der
  * Inhalt eines Knotens (Variable aktuellerKnoten) gleich
  * der einzufügenden Zeichenkette ist oder alphabetisch
  * hinter ihr steht.
  * Der neue Knoten muss dann VOR diesem Knoten eingefügt werden.
  * Deshalb wird in einer zweiten Variablen jeweils der Knoten
  * mitgeführt, der vor dem aktuellen Knoten steht.
  */
  Listenknoten aktuellerKnoten = this.listenkopf;
  Listenknoten vorherigerKnoten = null;

  /* Hinweis: Die Methode compareTo der Klasse String ermöglicht
  * die Untersuchung, in welcher lexikografischen Ordnung
  * zwei Zeichenketten zueinander stehen. Ein String s1 ist
  * lexikografisch kleiner s2, wenn s1.compareTo(s2) < 0.
  */

  /* Solange die Liste durchlaufen, wie noch nicht das Ende
  * erreicht ist und der Inhalt des aktuellen Knotens alphabetisch
  * vor der einzufügenden Zeichenkette steht.
  */
  while ((aktuellerKnoten != null)
  && (aktuellerKnoten.gibInhalt().compareTo(inhalt) < 0)) {

  /* Um einen Knoten weiterrücken.
  */
  vorherigerKnoten = aktuellerKnoten;
  aktuellerKnoten = aktuellerKnoten.gibNachfolger();
  }

  if (vorherigerKnoten == null) {

  /* Die Schleife wurde nicht betreten.
  * Der Knoten muss vorne eingefügt werden.
  */
  knoten.setzeNachfolger(this.listenkopf);
  this.listenkopf = knoten;
  
  } else {

  /* Knoten wird nicht vorne eingefügt. Listenkopf bleibt
  * unverändert. Knoten wird zwischen vorherigerKnoten und
  * aktuellerKnoten eingefügt.
  */
  vorherigerKnoten.setzeNachfolger(knoten);
  knoten.setzeNachfolger(aktuellerKnoten);

  /* Listenende neu setzen, wenn Knoten als letzter
  * Knoten eingefügt wurde. */
  if (aktuellerKnoten == null) {
  this.listenende = knoten;
  }
  }
  }
  this.listenlaenge = this.listenlaenge + 1;
  }

  /**
  * Entfernt die Zeichenkette an der angegebenen Position aus
  * dieser Liste.
  *
  * @param index  Index der Zeichenkette, die entfernt werden soll
  */
  public void entferne(int index) {

  if ((index >= 0) && (index < this.listenlaenge)) {

  if (index == 0) {

  /* Die Liste ist nicht leer und es soll der erste Knoten
  * entfernt werden.
  */
  this.listenkopf = this.listenkopf.gibNachfolger();

  /* Enthielt die Liste zuvor nur einen Knoten, so ist
  * anschließend auch das Listenende die null-Referenz.
  */
  if (this.listenkopf == null) {
  this.listenende = null;
  }

  this.listenlaenge = this.listenlaenge - 1;

  } else {

  /* Die Liste ist nicht leer und es wird ein mittlerer
  * oder der letzte Knoten entfernt.
  */

  /* Durch die Liste laufen, sodass anschließend aktuellerKnoten
  * den Knoten enthält, der entfernt werden soll, und
  * vorherigerKnoten seinen Vorgänger.
  */
  Listenknoten aktuellerKnoten = this.listenkopf;
  Listenknoten vorherigerKnoten = null;
  for (int i = 1; i <= index; i = i + 1) {
  vorherigerKnoten = aktuellerKnoten;
  aktuellerKnoten = aktuellerKnoten.gibNachfolger();
  }

  /* Der Knoten wird entfernt, indem sein Nachfolger zum
  * Nachfolger des Vorgängers wird.
  */
  vorherigerKnoten.setzeNachfolger(
  aktuellerKnoten.gibNachfolger());

  /* Wurde der letzte Knoten entfernt, muss das Listenende
  * aktualisiert werden.
  */
  if (vorherigerKnoten.gibNachfolger() == null) {
  this.listenende = vorherigerKnoten;
  }

  this.listenlaenge = this.listenlaenge - 1;
  }
  }
  }

  /**
  * Verkettet die übergebene Liste mit dieser Liste. Es wird keine
  * Kopie der übergebenen Liste erstellt.
  *
  * @param liste  Liste, die mit dieser Liste verkettet werden soll
  */
  public void verkette(VerketteteListe liste) {

  if (this.listenkopf == null) {

  /* Diese Liste ist leer. Der Kopf der anzuhängenden Liste wird
  * Kopf der verketteten Liste.
  */
  this.listenkopf = liste.listenkopf;

  } else {

  /* Diese Liste ist nicht leer. Der Kopf der anzuhängenden Liste wird
  * an das Ende dieser Liste angefügt.
  */
  this.listenende.setzeNachfolger(liste.listenkopf);
  }

  /* Listenende der anzuhängenden Liste wird zum Listenende dieser
  * Liste, wenn die anzuhängende Liste nicht leer ist.
  */
  if (liste.listenkopf != null) {
  this.listenende = liste.listenende;
  }

  /* Längen der Listen addieren sich.
  */
  this.listenlaenge = this.listenlaenge + liste.listenlaenge;
  }

  /**
  * Liefert die Zeichenkette an der angegebenen Position in der Liste.
  * Ist der Index ungültig, wird null zurückgegeben.
  *
  * @param index  Index der Zeichenkette
  * @return Zeichenkette an der angegebenen Position
  */
  public String gibInhalt(int index) {

  String inhalt;

  if ((index < 0) || (index >= this.listenlaenge)) {
  // Fehlerfall: muss geeignet behandelt werden
  inhalt = null;
  } else {

  /* Solange die Liste durchlaufen, bis k den angegebenen
  * Listenknoten enthält.
  */
  Listenknoten k = this.listenkopf;
  for (int i = 1; i <= index; i++) {
  k = k.gibNachfolger();
  }
  inhalt = k.gibInhalt();
  }

  return inhalt;
  }

  /**
  * Liefert die Länge dieser Liste.
  *
  * @return Länge der Liste
  */
  public int gibLaenge() {

  return this.listenlaenge;
  }

  /**
  * Liefert String-Darstellung der Liste im Format
  * Listenkopf: k, Listenende: e, Listeninhalt: i
  * Die String-Darstellung ist so gewählt, dass sie interne Details
  * der Liste zu Anschauungszwecken zeigt.
  * k ist "null", wenn der Listenkopf die null-Referenz ist, sonst
  * der Inhalt des Kopfknotens.
  * e ist "null", wenn das Listenende die null-Referenz ist, sonst
  * der Inhalt des Ende-Knotens.
  * i ist durch Leerzeichen getrennt die Folge der Knoteninhalte.
  *
  * @return String-Darstellung dieser Liste
  */
  public String gibAlsString() {

  String ergebnis = "Listenkopf: "
  + ((this.listenkopf == null)
  ? "null"
  : this.listenkopf.gibInhalt())
  + ", ";

  ergebnis = ergebnis + "Listenende: "
  + ((this.listenende == null)
  ? "null"
  : this.listenende.gibInhalt())
  + ", ";

  ergebnis = ergebnis + "Listeninhalt:";

  Listenknoten k = this.listenkopf;

  /* Inhalte aller Knoten aneinanderfügen.
  */
  while (k != null) {
  ergebnis = ergebnis + " " + k.gibInhalt();
  k = k.gibNachfolger();
  }

  return ergebnis;
  }
}

Code:
/**
 * Ein Listenknoten repräsentiert einen Knoten einer einfach verketteten
 * Liste. Ein Knoten enthält einen Inhalt und einen Nachfolgeknoten.
 */
public class Listenknoten {

  /**
  * Inhalt dieses Knotens.
  */
  private String inhalt;

  /**
  * Nachfolgender Listenknoten.
  */
  private Listenknoten nachfolger;

  /**
  * Erzeugt einen neuen Listenknoten mit der übergebenen
  * Zeichenkette als Inhalt.
  *
  * @param inhalt  Inhalt dieses Listenknotens
  */
  public Listenknoten(String inhalt) {

  this.inhalt = inhalt;
  this.nachfolger = null;
  }

  /**
  * Erzeugt einen neuen Listenknoten mit der übergebenen
  * Zeichenkette als Inhalt und dem übergebenen Knoten
  * als Nachfolger.
  *
  * @param inhalt  Inhalt dieses Listenknotens
  * @param nachfolger  Nachfolger dieses Listenknotens
  */
  public Listenknoten(String inhalt, Listenknoten nachfolger) {

  this.inhalt = inhalt;
  this.nachfolger = nachfolger;
  }

  /**
  * Liefert den Inhalt dieses Listenknotens.
  *
  * @return Inhalt dieses Listenknotens
  */
  public String gibInhalt() {

  return this.inhalt;
  }

  /**
  * Liefert den nachfolgenden Listenknoten.
  *
  * @return nachfolgender Listenknoten
  */
  public Listenknoten gibNachfolger() {

  return this.nachfolger;
  }

  /**
  * Weist diesem Listenknoten einen neuen Nachfolger zu.
  *
  * @param knoten  Nachfolger dieses Listenknotens
  */
  public void setzeNachfolger(Listenknoten knoten) {

  this.nachfolger = knoten;
  }
}
 

Flown

Administrator
Mitarbeiter
Ich wusste doch, dass ich noch was aus meiner HTL-Zeit herumliegen hatte: Hier mal wie sowas aussehen kann:
Java:
class SinglyLinkedList<T> {

  private ListNode head = null;

  public SinglyLinkedList() {
  }

  public T valueAt(int pos) {
    ListNode node = nodeAt(pos, head);
    return node == null ? null : node.value;
  }

  public void insertAt(int pos, T value) {
    ListNode toInsert = new ListNode(value);
    if (pos == 0) {
      if (head != null) {
        toInsert.next = head;
      }
      head = toInsert;
    } else {
      ListNode previous = nodeAt(pos - 1, head);
      if (previous != null) {
        toInsert.next = previous.next;
        previous.next = toInsert;
      }
    }
  }

  public void removeAt(int pos) {
    if (pos == 0) {
      if (head != null) {
        head = head.next;
      }
    } else {
      ListNode previous = nodeAt(pos - 1, head);
      if (previous != null) {
        ListNode cur = previous.next;
        previous.next = cur == null ? null : cur.next;
      }
    }
  }

  private ListNode nodeAt(int pos, ListNode node) {
    if (pos <= 0) {
      return node;
    } else {
      return node == null ? null : nodeAt(pos - 1, node.next);
    }
  }

  @Override
  public String toString() {
    if (head == null) {
      return "[ ]";
    }
    StringBuilder builder = new StringBuilder();
    builder.append("[ ");
    for (ListNode ln = head; ln != null; ln = ln.next) {
      if (ln != head) {
        builder.append(", ");
      }
      if (ln.value == this) {
        builder.append("(this SinglyLinkedList)");
      } else {
        builder.append(ln.value);
      }
    }
    return builder.append(" ]").toString();
  }

  class ListNode {
    private ListNode next;
    private T value;
  
    public ListNode(T value) {
      this.value = value;
    }
  
    public ListNode(T value, ListNode next) {
      this(value);
      this.next = next;
    }
  }
}

PS: Man muss nichts in ListKnoten ändern.
 
Zuletzt bearbeitet:

Neue Themen


Oben