Einfach verkettete Liste mit Listenendezeiger



  • Gut, mag sein. Allerdings: was ist das Ende? Ist das der letzte next-Zeiger (der wäre nullptr, das geht also nicht) oder das letzte existierende Element (was ist dann mit leeren Listen?)?

    Und wenn man die Aufgabe

    Meine Aufgabe ist es allerdings nicht mehr den Listenanfang zu übergeben sondern das Listenende dies muss auch wieder an die main Funktion zurückgegeben werden. Jedes weitere "einfügen" bekommt auch das "listenende" sowie die "ausgabe" und das "löschen" der Liste.

    so liest, dass "löschen" nun auch als Parameter das Ende bekommen soll, ist das gänzlich wertlos - denn wie soll man korrekt löschen können, ohne den Anfang zu kennen? Irgendwas stimmt hier doch nicht.



  • Ja, da hast du recht. Ich denke dass der Teil mit dem Ausgeben und Löschen aus dem Zusammenhang geraten ist. Funktioniert bei einer einfach verketteten Liste ja auch nicht über das letzte Element.



  • Also erstmal Danke für die vielen und schnellen Antworten.

    Anbei nochmal die Fragestellung etwas genauer.

    Es geht hier darum in der Funktion -anhaengen- das Listenende zu übergeben bzw. zu ermitteln, dieses aber auch wieder an die -main- Funktion zurückzugeben um damit weiter "arbeiten" (als Argument beim Anhängen übergeben) zu können.
    Es soll damit bezweckt werden dass nicht immer erst vom ersten bis zum letzten Element "gewandert" werden muss, sondern gleich das letzte Element bekannt ist.

    *Die Funktion -ausgabe- und -löschen- bekommen weiterhin den Listenanfang!

    Es muss allerdings dafür gesorgt werden das dass -Listenende- nach jedem anhängen neu ermittelt wird. Ich habe schon etliche Wege probiert wie z.Bsp. zwei weitere Zeiger (Pointer) - *begin und *last - in der Struktur (struct) einzufügen und mit denen zu arbeiten allerdings kann ich diese nicht an die -main- Funktion zurückgeben.

    Falls ihr meine Lösungsverusche sehen wollt, kann ich diese natürlich auflisten.

    Meine Frage wäre ob denn wer einen Weg kennt den Quellcode nicht Großartig zu ändern sondern rein die Funktion -aendern- zu ändern. Ich bin hier nicht auf Lösungen aus sondern rein auf Ansatzwege.

    Danke im Voraus.



  • Du hast es in 6 Stunden nicht geschafft meinen Beitrag anzusehen und auszuprobieren?



  • inflames2k schrieb:

    Du hast es in 6 Stunden nicht geschafft meinen Beitrag anzusehen und auszuprobieren?

    Nein hatte ich leider noch nicht bis jetzt.

    Hier meine Version davon, allerdings wird mir nur immer das letzte Element ausgegeben. Liegt das daran weil ich den Zeiger immer wieder überschreibe oder?

    #include <iostream>
    
    using namespace std;
    
    //Die Struktur für die Listenelemente
    struct listenelement
    {
        string daten;
        listenelement *next;
    };
    
    //Eine Funktion zu Anhängen von Elementen an die Liste
    listenelement *anhaengen (string datenneu, listenelement *listenende)
    {
        //Ein lokaler Hilfszeiger, um in deer Liste wandern zu können
        listenelement *hilfszeiger;
        //den Hilfszeiger auf das letzte Element setzen
        hilfszeiger = listenende;
        while (hilfszeiger->next != nullptr)
        { hilfszeiger = hilfszeiger->next;
        }
    
        hilfszeiger->next = new(listenelement);
        listenende = hilfszeiger->next;
        hilfszeiger->daten = datenneu;
        hilfszeiger->next = nullptr;
    
         return listenende;
    }
    
    //Eine Funktion zum ausgeben aller Elemente
    void ausgabe(listenelement *listenanfang)
    {
        //Ein lokaler Hilfszeiger, um in deer Liste wandern zu können
        listenelement *hilfszeiger;
        //den Hilfszeiger auf den Anfang der Liste setzen
        hilfszeiger = listenanfang;
        cout << hilfszeiger->daten << '\n';
    
        while (hilfszeiger->next != nullptr)
        {
            hilfszeiger = hilfszeiger->next;
            //Daten ausgeben
            cout << hilfszeiger->daten << '\n';
        }
    }
    
    //die Liste leeren und Speicher freigeben
    void ende(listenelement *listenanfang)
    {
        //Ein lokaler Hilfszeiger, um in der Liste wandern zu können
        listenelement *hilfszeiger;
        //Solange noch Elemente in der Liste sind
        while (listenanfang != nullptr)
        {
            hilfszeiger = listenanfang;
            listenanfang = listenanfang->next;
            //den Speicher für das herausgenommene Element freigeben
            delete(hilfszeiger);
        }
    }
    
    int main()
    {
    
        //ein Zeiger auf den Anfang der Liste setzen
        listenelement *listenanfang, *listenende;
        //das erste Element erzeugen
        listenanfang = new(listenelement);
        //Daten in das erste Element schreiben
        listenanfang->next = nullptr;
        listenanfang->daten = "Daten in Liste 1";
    
        listenende = listenanfang;
    
        //und jetzt weitere Elemente erzeugen
        anhaengen("Daten in Liste 2", listenende);
        anhaengen("Daten in Liste 3", listenende);
        anhaengen("Daten in Liste 4", listenende);
        anhaengen("Daten in Liste 5", listenende);
    
        //die Liste ausgeben
        ausgabe(listenanfang);
        //die Liste wieder abbauen
        ende(listenanfang);
    
        return 0;
    }
    


  • Hauptsächlich liegt es an fehlerhaftem Code.

    Der Hilfszeiger in anhaengen ist unnötigt, nur die letzten 5 Codezeilen sind relevant. Alles andere kann raus.

    //Eine Funktion zu Anhängen von Elementen an die Liste
    listenelement *anhaengen (string datenneu, listenelement *listenende)
    {
        //Ein lokaler Hilfszeiger, um in deer Liste wandern zu können
        listenelement *hilfszeiger;
        //den Hilfszeiger auf das letzte Element setzen
        hilfszeiger = listenende;
        while (hilfszeiger->next != nullptr)
        { hilfszeiger = hilfszeiger->next;
        }
    
        hilfszeiger->next = new(listenelement);
        listenende = hilfszeiger->next;
        hilfszeiger->daten = datenneu;
        hilfszeiger->next = nullptr;
    
         return listenende;
    }
    

    In deiner Main musst du auch listenende mit dem Rückgabewert überschreiben.

    listenende = anhaengen("Daten in Liste 2", listenende);
    

    Andernfalls hängst du immer wieder an das Startelement Daten an und setzt danach den Null-Pointer.

    IDEOne



  • Ja genau so funktioniert es prima!

    das verwende ich jetzt auch.
    Aber gibt es noch eine andere Möglichkeit außer über die return Funktion diese Aufgabe umzusetzen. Wahrscheinlich über Klassen und listen?!



  • Ist nicht unbedingt die sauberste Variante, aber mit einer einfachen Klasse: IDE One



  • theprofile schrieb:

    Aber gibt es noch eine andere Möglichkeit außer über die return Funktion diese Aufgabe umzusetzen. Wahrscheinlich über Klassen und listen?!

    Ja.

    Du kannst der Funktion anhaengen z.B. einen Zeiger auf einen Zeiger auf listenelement übergeben. Dann kann die Funktion direkt den listenelement -Zeiger im main ändern.

    Das selbe kannst du in C++ auch erreichen indem du eine Referenz auf einen Zeiger auf listenelement übergiebst. Dabei ändert sich in diesem Fall lediglich die Syntax leicht.

    => Google dich zum Thema "Zeiger auf Zeiger" und "Referenzen" schlau.

    Die Frage ist dann bloss noch ob das so gewünscht ist. Wäre leicht möglich dass euer Lehrer/Vortragender die listenende = anhaengen("Daten in Liste 2", listenende); Variante haben möchte. Oder auch ganz 'was anderes. z.B. wäre auch anhaengen("Daten in Liste 2", listenende); listenende = finde_ende(listenende); denkbar, oder einfach anhaengen("Daten in Liste 2", listenende); listenende = listenende->next; .



  • Okay super, Danke.
    Werd mich mal schlau machen.


Anmelden zum Antworten