DoublyLinkedList

Javanoob199

Mitglied
Hallo, ich muss hier eine Aufgabe für die Schule lösen, verstehe aber komplett nicht wie ich das machen soll. Das wäre mein Ansatz, aber ich verstehe nicht wie ich die 2 Elemente vertauschen soll.
Hier ist die Aufgabestellung: Vervollständigen Sie die Methode void exchange(). Die Methode exchange soll die ersten beiden vom Listenanfang aus erreichbaren Inhalte, die nicht null sind, miteinander vertauschen. Gibt es keine zwei Inhalte, die ungleich null sind, soll nichts geschehen.
Mir stehen die Methoden connectAsSucc(Element), connectAsPred(Element),getSucc(),getPred(),dissconnectSucc() und dissconnectPred() zur Verfügung, wobei Succ der Nachfolger ist und Pred das Element davor.
Ich würde mich über jede Hilfe freuen:)

Java:
Element current= first;
        Element firstHit= current.getSucc();
        while(!isEmpty())
        {
             if(current.getContent()==null)
             {
                 current=current.getSucc();
                 firstHit=firstHit.getSucc();
             }
             else if(firstHit.getContent()==null)
             {
                 firstHit=firstHit.getSucc();
             }
             else
             {
                    
             }
        }
 

Jw456

Top Contributor
Wie würdest du denn in einem Array zwei Elemente tauschen.
Doch wohl mit einer Hilfs Variablen.

hilfsvar = erstes Element
zweites Element = erstes Elemente
erstes Elemente = hlifsvar
 

mihe7

Top Contributor
Gut, das sind ja erstmal zwei Teilaufgaben:

I) Finde, ausgehend von einem Element, das erste Element, dessen Inhalt ungleich null ist.

Mit der Lösung dieser Teilaufgabe kannst Du die beiden zu vertauschenden Elemente finden. Dann

II) Vertausche die beiden Elemente
 

Javanoob199

Mitglied
Ich habe jetzt das als Code und es wird was ausgegeben, aber die 2 Elemente werden nicht vertauscht sondern es kommt die von mir eingegebene Liste einfach wieder. Ich verstehe nicht ganz wie ich die Elemente vertauschen kann.

Java:
public void exchange ()
    {
        Element current= first;
        Element firstHit= current.getSucc();
        while(current==null||firstHit==null)
        {
             if(current.getContent()==null)
             {
               current=current.getSucc(); 
               firstHit=firstHit.getSucc();
             }
             else if (firstHit.getContent()==null)
             {
                 firstHit=firstHit.getSucc();
             }
             else
             {
                 Element n = firstHit.getSucc();
                 n.connectAsSucc(current);
                 firstHit.connectAsPred(current);
             }
        }
    }
 

Jw456

Top Contributor
Dazu wäre es sinnvoll zu erklären was die vorhanden Methoden genau machen und was sie zurück geben.

Dabei kommst du vielleicht auch selber drauf was du machen könntest um den Anfang der Liste zu finden.
Hast du denn dann teste ob der Innhalt nicht null ist .
Teste ob vom nächsten Element der Inhalt nicht Null ist.

Dazu brauchst du natürlich eine Methode mit der du den Inhalt eines Element lesen kannst und zum tauschen auch eine mit der du den Inhalt eines Element schreiben kannst.
Welche das sind das weist du, du hast die Library wir nicht.


Du schreibst deine Liste wird ausgegeben, mit welcher Methode gibst du denn in deinen Code etwas aus? Ich sehe da nicht davon.
 
Zuletzt bearbeitet:

Javanoob199

Mitglied
Mein Element Current ist doch das erste Element der Liste und da prüfe ich ja ob der Inhalt leer ist mit getContent und mit firstHit ist ja das zweite Element und da prüfe ich auch ob das Element leer ist. Ich verstehe nur nicht wie ich die 2 tauschen soll.
Außerdem schreie ich nicht, ich sage nur was mir ausgeben wird und dazu habe ich eine andere Klasse geschrieben. Es ist ja nicht wichtig was genau in der Liste ist sondern einfach dass die Liste gleich bleibt oder nicht
Aber zum Verständnis hier ist mein Code für die Ausgabe der Liste.
Java:
public class TU6
{
    public static void main( String[] args )
    {
        testDoublyLinkedList();
    }
        
    public static void testDoublyLinkedList()
    {
        Object obj= 17;
        DoublyLinkedList integers = new DoublyLinkedList();
        integers.add( 4 );
        integers.add( 5);
        integers.add( 4 );
        integers.add( 17 );
        integers.add( 7 );
        integers.add( 4 );
        integers.add( 11 );
        integers.add( 4 );
        integers.showAll();
        integers.exchange();
        integers.showAll();
    }
}
 

mihe7

Top Contributor
Ich habe jetzt das als Code und es wird was ausgegeben, aber die 2 Elemente werden nicht vertauscht sondern es kommt die von mir eingegebene Liste einfach wieder.
Dein Code enthält Fehler und ist zu kompliziert.

Die Aufgabenstellung ist evtl. auch aus dem Kontext gerissen und damit für uns auch nicht ganz eindeutig, weil wir nicht wissen, wie die Liste tatsächlich aufgebaut ist und welche Möglichkeiten die Elemente bieten.

Ich gehe mal davon aus, dass der Inhalt von first tatsächlich der erste von first aus erreichbare Inhalt ist (der null sein kann). Wenn der Inhalt von first gleich null ist, muss weitergesucht werden, bis es entweder kein Element mehr gibt oder ein passender Inhalt gefunden wurde:
Java:
Element current = first;
while (curent != null && current.getContent() == null) {
    current = current.getSucc();
}
Offensichtlich ist nach der Schleife current entweder null, dann wurde kein Element gefunden, oder current referenziert ein Element, dessen Inhalt ungleich null ist.
Java:
if (current == null) {
    return; // es gibt kein Element mit einem Inhalt ungleich null
}
Element firstHit = current;

Für das zweite Element kannst Du nun die gleiche Schleife noch einmal verwenden, musst lediglich current auf firstHit.getSucc() setzen. Das schreit nach einer Methode:

Java:
private Element nextElementWithContent(Element start) {
    Element current = start;
    while (curent != null && current.getContent() == null) {
        current = current.getSucc();
    }
    return current;
}

In Deiner exchange-Methode kannst Du jetzt schreiben:
Java:
Element firstHit = nextElementWithContent(first);
if (firstHit == null) {
    return;
}
Element secondHit = nextElementWithContent(firstHit.getSucc());
if (secondHit == null) {
    return;
}

Ja, man kann das auch in einer Schleife erledigen - der Code wird aber unnötig komplex (es ist nicht mehr so einfach, die Funktion der Schleife nachzuvollziehen):
Java:
Element firstHit = null;
Element secondHit = null;

Element current = first;
while (current != null && secondHit == null) {
    if (current.getContent() != null) {
        if (firstHit == null) {
            firstHit = current;
        } else {
            secondHit = current;
        }
    }
    current = current.getSucc();
}
if (firstHit == null || secondHit == null) {
    return;
}

Im Anschluss musst Du noch die beiden Elemente vertauschen. Auch hier wieder ist uns nicht klar, ob Du die Inhalte der Elemente verändern kannst. Falls ja, muss Du nur die Inhalte vertauschen und bist fertig. Sonst wird es komplizierter und wenn ich lese
Mir stehen die Methoden connectAsSucc(Element), connectAsPred(Element),getSucc(),getPred(),dissconnectSucc() und dissconnectPred() zur Verfügung, wobei Succ der Nachfolger ist und Pred das Element davor.
gehe ich auch davon aus, dass es komplizierter werden soll :)

Hier hilft es, sich das mal die alte und die neue Situation, also vor und nach dem Vertauschen, aufzuzeichnen
1642862715607.png
Die roten bzw. blauen Markierungen sollen dabei deutlich machen, dass hier tatsächlich Elemente und nicht nur Inhalte vertauscht werden.

In der Zeichnung fällt einiges auf:
  1. Ich habe den ersten Knoten als Kopf bezeichnet. Das wäre first, dessen Inhalt null ist. Das muss nicht so sein, es kann auch first von der Vertauschung betroffen sein.
  2. Zwischen A und B liegen Knoten, deren Inhalt null sind. Das muss nicht so sein, A und B könnten auch aufeinanderfolgen.
  3. B ist der letzte Knoten der Liste. Das muss nicht so sein, es könnten weitere Knoten folgen.
Du solltest Dir alle Fälle aufzeichnen, um nachvollziehen zu können, was beim Vertauschen passiert.

Bleiben wir mal bei dem Bild. Mit A und B werde ich jetzt Elemente und keine Inhalte ansprechen.

Was passiert vorne? B wird als Nachfolger des alten Vorgängers von A und als Vorgänger des alten Nachfolgers von A verknüpft. Umgekehrt wird der alte Vorgänger von A als Vorgänger von B und der alte Nachfolger von A als Nachfolger von B eingetragen.

Und hinten? Genau das gleiche, nur dass A und B vertauschte Rollen einnehmen. Natürlich gilt zu beachten, dass B im Bild keinen Nachfolger hat.

Hinzu kommen nun die anderen Fälle: der alte Vorgänger von A kann null sein, wenn es sich bei A um den Listenkopf handelt. Hier muss dann auch first angepasst werden. Zu allem Überfluss muss das Vertauschen ein klein wenig anders laufen, wenn A und B unmittelbar aufeinanderfolgen.

Daher nochmal: Du solltest Dir alle Fälle aufzeichnen, um nachvollziehen zu können, was beim Vertauschen passiert. Bevor Du nicht weißt, was zu tun ist, brauchst Du keine Zeile Code zu schreiben.
 

Jw456

Top Contributor
Frage eine Methode getContent() du zum lesen des Inhaltes hast, hast du auch eine zum Schreiben?
setContent() vielleicht.
 

Javanoob199

Mitglied
Danke für die ausführliche Antwort:) Ich habe nochmal nachgefragt, welche Methoden ich für diese Aufgabe benutzen darf, da ich in meiner Klausur später nur bestimmte Methoden einer Klasse zur Verfügung habe.
Diese Methoden dürfen wir für solche Aufgaben benutzen:
// Element private static class Element {
private T content;
private Element pred, succ;
public Element( T c ) { ... }
public T getContent() { ... }
public void setContent( T c ) { ... }
public boolean hasSucc() { ... }
public Element getSucc() { ... }
public void connectAsSucc( Element e) { ... }
public void disconnectSucc() { ... }
public boolean hasPred() { ... }
public Element getPred() { ... }
public void connectAsPred( Element e ) { ... }
public void disconnectPred() { ... }

public class DoublyLinkedList {
private Element first, last;
private int size;
public DoublyLinkedList() { ... }
public int size() { ... }
public boolean isEmpty() { ... }
Außerdem wurde ich darauf hingewiesen, dass wir nicht einfach weitere Methoden erstellen können und die Methode wie folgt aussehen muss und wir halt nur in die while-Schleife etwas einfügen können und current&firstHit bestimmen dürfen. Die Aufgabenstellung, die ich am Anfang reingeschickt habe ist die vollständige Aufgabenstellung und mehr habe ich auch nicht bekommen
Java:
public void exchange(){
Element<T> current=...
Element<T> firstHit=...
    while()
    {
        //hier Code einfügen
    }
    
}
 

mihe7

Top Contributor
Gut, dann ist die Sache einfach.
Java:
while (current != null) {
    if (current.getContent() != null) {
        if (firstHit == null) {
            firstHit = current;
        } else {
            int tmp = firstHit.getContent();
            firstHit.setContent(current.getContent());
            current.setContent(tmp);
            break;
        }
    }
    current = current.getSucc();
}
 

jari

Aktives Mitglied
Wenn die Verkettung geändert werden soll, musst du 8 Referenzen ändern (wenn beide Elemente nicht am Rand liegen).
Wenn nur der Inhalt vertauscht werden soll, ist es ja trivial.
Also überlege dir vorher ob "Behälter" oder "Inhalt " getauscht werden sollen.
 

Ähnliche Java Themen

Neue Themen


Oben