Verkettete liste rückwärts ausgeben

Nocturnis

Mitglied
das neue element ist immer mit dem vorherigen verknüpft durch Listenelement letzter. Jetzt würde ich das gerne rückwärts ausgeben durch eine rekursion und da haperts bei mir momentan. rekursiv ist die methode "ausgeben" aber sie tut nicht was sie soll... Sie gibt mir nur das Listenende aus aber nicht die vorherigen elemente. vllt hab ich da einen denkfehler beim Listenelement letzter bitte helft mir.
Außerdem würde ich gerne wissen wie ihr das finden des letzten elements ohne einen konstruktor gemacht hättet. (neugierdehalber)
class Listenelement {
String daten;
Listenelement naechster;
Listenelement letzter;
public Listenelement (Listenelement letzter){
this.letzter = letzter;

}
public Listenelement getprev (){
return letzter;
}
void setnext (Listenelement naechster){
this.naechster = naechster;
}
Listenelement getend(){
return Listend;
}

void setDaten(String datenNeu) {

this.daten = datenNeu;

this.naechster = null;
}
static Listenelement Listend = null;
Listenelement hilf=null;
void anhaengen(String datenNeu) {

if (naechster == null) {
naechster = new Listenelement(naechster);
naechster.setDaten(datenNeu);
Listend = naechster;


}

else
naechster.anhaengen(datenNeu);

System.out.println("Daten " + datenNeu + " wurden eingefügt.");
}

void ausgeben() {

System.out.println(daten);
if (letzter != null)
letzter.ausgeben();




}
}
public class aufgtest {
public static void main(String[] args) {

Listenelement listenAnfang = new Listenelement(null);
listenAnfang.setDaten("Element 1");
for (int element = 2; element < 10; element++)
listenAnfang.anhaengen("Element " + element);

Listenelement.Listend.ausgeben();
}
}
 
Die Logik ist ganz easy:
Java:
    Node reverse(Node node) {
        Node prev = null;
        Node current = node;
        Node next = null;
        while (current != null) {
            next = current.next;
            current.next = prev;
            prev = current;
            current = next;
        }
        node = prev;
        return node;
    }
 
so wie bei einer doppelt verketteten liste also. ich dachte nur ich könnte das irgendwie anders machen, so das ich quasi current weglasse und den prev auf den vorherigen next setze.
danke für die hilfe ich werde das gemäß deiner antwort umsetzen.
nichts desto trotz wäre es interressant zu wissen ob es so wie ich es mir dachte funktionieren würde.
 
Zuletzt bearbeitet:
das neue element ist immer mit dem vorherigen verknüpft durch Listenelement letzter.
Wenn ich es richtig sehe (verwende bitte Code-Tags: [code=Java]Dein Code[/code]), dann nicht und das dürfte auch das Problem verursachen sein:
Java:
if (naechster == null) {
    naechster = new Listenelement(naechster);
    ...
müsste lauten
Java:
if (naechster == null) {
    naechster = new Listenelement(this);
    ...

Ansonsten: schmeiß die static-Variable raus. Du kannst die Ausgabe auch von vorne rückwärts ausgeben.
Java:
public void ausgeben() { 
    if (naechster != null) { naechster.ausgeben(); }
    System.out.println(daten);
}
 
Java:
public void ausgeben() {
    if (naechster != null) { naechster.ausgeben(); }
    System.out.println(daten);
}
Ich muss hier mal dazwischen Fragen, es wird so lange die Methode von sich selbst aufgerufen bis 'naechster' gleich null ist.
Warum werden dann die 'daten' ohne das die Methode aufgerufen wird allesamt nacheinander ausgegeben?
 
erstens ist diser Thread schon alt.

Es wird ja die Methode Ausgabe den nechten Objekt aufgerufen mit "naechster.ausgeben();"
wie bei einem Zug von Wagen zu Wagen der letzte ist null.
Das ist nicht die Methode von dem Wagen in dem du bist sondern die von nechsten Wagen.
 
Ich habe bei den Code mal verschiedene println eingebaut.
Erst wird als erstes nur 1 und 2 ausgegeben, wenn "naechster" null ist wird nur noch 3 und die Daten ausgegeben. Was ich nicht verstehe, warum dann nicht 1 ausgegeben wird und in der if-Anweisung nur noch 3 und nicht die 2.
Da ist man ja quasi in der if-anweisung, aber wird die 2 nicht ausgegeben. Warum verstehe ich nicht.

Java:
public void ausgeben() {
    System.out.println("1 " + naechster);
    if (naechster != null) {
        System.out.println("2 " + naechster);
        naechster.ausgeben();
        System.out.println("3 " + naechster);
                           }
    System.out.println(daten);
}
 
Ausgabe nur 3 kann nicht sein.

Bei drei Wagen
1
2
3
Daten

1
2
3
Daten

1
Daten
Wenn es anders ist hast du deine Liste nicht richtig erstellt.


Versuche es zuverstehen du bist immer wider in einen neuen Objekt auch wenn die beim duchgehen mit den Debugger gleich aussehen.
Du hast eine Klasse den Bauplan und von diesem hast du viele Objekte (Wagen) erstellt die alle gleich ausschauen aber eine andere ladung haben.
 
Warum werden dann die 'daten' ohne das die Methode aufgerufen wird allesamt nacheinander ausgegeben?
Warum nicht? Die Liste soll ja rückwärts ausgegeben werden.

Nehmen wir mal eine Liste mit drei Elementen, die ich mal als element1, element2 und element3 bezeichne und die in genau dieser Reihenfolge auch verkettet sind. Ablauf:

Code:
element1.ausgeben():
  naechster == element2, also nicht null, also folgt folgender Aufruf
  element2.ausgeben():
    naechster == element3, also nicht null, also folgt folgender Aufruf
    element3.ausgaben():
      naechster == null, also wird daten (von element3) ausgegeben
      Die Methode endet und kehrt zum Aufrufer zurück
    element3.ausgeben ist nun abgeschlossen, es wird daten (von element2) ausgegeben
    Die Methode endet und kehrt zum Aufrufer zurück
  element2.ausgeben ist nun abgeschlossen, es wird daten (von element1) ausgegeben
  Die Methode endet und kehrt zum Aufrufer zurück
Fertig.

Klar?
 
Eine einfach verkette Liste kannst du nicht von hinten durgehen.
Das Ende kennst du ja nicht.

Edit mihe7 . Ok so würde es gehen.
 
Zuletzt bearbeitet:
Eine Frage, nachdem ich es soweit verstanden habe bleibt aber noch, warum kehrt (siehe #13 Zeile 7) die Methode zum Aufrufer zurück und die Methode wird nicht beendet?
Normalerweise wird ja bei einen Programm der Code von oben nach unten abgearbeitet.
 
Das ist doch generell das Vorgehen bei Methodenaufrufen: die Methode wird aufgerufen und wenn die Methode fertig ist, dann geht es hinter dem Aufruf weiter.

Sonst würde das ja alles nicht funktionieren, denn vieles sind ja Methodenaufrufe: println bei einer Ausgabe oder die nextInt oder so Aufrufe beim Scanner.
 
Mit Zeile 7. meint er das die Methode sich selbst t nicht weiter aufruft und beendet. Nun werden alle Aufgerufen Methoden rückwärts wider beendet nicht aufgerufen.

Du bist ja die Kette vorwärts durchgegangen, ausgaben und beenden hast du noch nicht gemacht. Jetzt bist du im letzten Element dort machst du die Ausgabe die Methode wird beendet.



Beim aufruf einer Methode wird der Rücksprung auf einen Stapel im Speicher gelegt. Der am Ende abgearbeitet wird. Also es wird die Ausgabe gemacht und die Methode beendet. beim Beenden vom Stapel entfernt.
.
 

Neue Themen


Zurück
Oben