Ist die Aufgabe richtig gelöst? Struktur / verkettete Liste



  • Hallo,
    ich habe von meinem Professor folgenden Aufgabe bekommen:

    - Programmieren Sie eine verkettete Liste für den Datentyp float
    - Gegeben sind die Strukturen llistel und llist
    - llistel ist dabei die Struktur für das Listenelement, das die Daten und einen
    Pointer zum nächsten Element beinhaltet
    - llist ist dabei die Struktur für die Liste selbst, die den Pointer zu dem
    Listenkopf (first, erstes Element) beinhaltet
    - size soll angeben wiev iele Elemente sich gerade in der Liste befinden und
    beim Einfügen entsprechend erhöht werden
    - dazu muss ich zwei Funktionen programmieren. Einmal void llistcreatefront (struct llist* pllist, int num) mit der Funktion, dass es eine Liste mit Anzahl von „num“ Werten erstellt, wobei die Werte aufsteigende Zahlen von 0 beginnend
    sein sollen (z.B: num=10 -> 0,1,2,3,4,5,6,7,8,9)
    und llistprint (struct llist* pllist) welche das ganze ausgibt.
    - Die mein hab ich so bekommen und soll praktisch mit meinen Funktionen funktionieren

    Das ist mein Code:

    #include <iostream>
    
    using namespace std;
    
    struct llistel
    {
        float data;
        struct llistel *next;
    };
    
    struct llist
    {
        struct llistel *first;
        int size;
    };
    
    struct llistel kette[50];
    
    //void llistaddfront (struct llist* pllist, float fval){}                   //Funktion soll am Listenkopf ein Listenelemnt mit dem übergebenen float Wert einfügen
    
    void llistcreatefront (struct llist* pllist, int num)                       // Funktion soll eine List mit aAnzahl von num Werten erstellen, Werte aufsteiugend Zahlen von 0
    {
        kette[num];
        (*pllist).first = &kette[0];
        for(int i=0; i < num; i++)
        {
            kette[i].data = i;
            kette[i].next = &kette[i+1];
            (*pllist).size = (*pllist).size + 1;
            //cout << kette[i].data << endl;
        }
        kette[num - 1].next = nullptr;
        return;
     }
    
    void llistprint (struct llist* pllist)                                      // Die Funktion soll alle Listenelemente auf den Monitor ausgeben
    {
        llistel *actual;
        actual = (*pllist).first;
        //cout << (*pllist).first->data;
        while(actual != nullptr)
        {
            cout << actual->data << endl;
            actual = actual->next;
        }
    }
    
    int main()
    {
        llist llistvar;
    
        llistvar.size=0;
        llistvar.first=NULL;
    
        llistcreatefront(&llistvar,10);
    
        llistprint(&llistvar);
    
        return 0;
    }
    

    Jetzt zu meiner Frage. Da ja meine Main vorgegeben ist und ich nur den Pointer der Strukutr übermittel welcher wiederum einen Zeiger auf meine Liste binhaltet muss ich doch die llistel kette global erzeugen mit nem Wertebereich oder? Oder übersehe ich dass man die Liste erzeugen kann ohne kette zu erstellen?

    Sieht das ok aus? Was meint ihr? 😃



  • eule_123 schrieb:

    muss ich doch die llistel kette global erzeugen mit nem Wertebereich oder?

    Nein.

    eule_123 schrieb:

    Oder übersehe ich dass man die Liste erzeugen kann ohne kette zu erstellen?

    Ja.
    Das nennt sich dynamischer Speicher und wird in C++ mit new und delete erledigt bzw. auch nicht mehr, weils ja std::vector gibt.

    eule_123 schrieb:

    Sieht das ok aus? Was meint ihr? 😃

    Sorry, soweit habe ich noch nicht geschaut.



  • Zeile 23 bewirkt genau garnichts.



  • Du lernst gerade C mit cout.
    Wenn das

    void llistcreatefront (struct llist* pllist, int num)
    

    genau so vorgegeben ist, beherrscht der Aufgabensteller auch kein C++: das struct ist dort, wie auch noch an anderen Stellen in deinem Programm, in C++ überflüssig.



  • Na hauptsache er kann nachher Bäumchen machen.



  • manni66 schrieb:

    Du lernst gerade C mit cout.
    Wenn das

    void llistcreatefront (struct llist* pllist, int num)
    

    genau so vorgegeben ist, beherrscht der Aufgabensteller auch kein C++: das struct ist dort, wie auch noch an anderen Stellen in deinem Programm, in C++ überflüssig.

    Das ist so angegeben ja und hat sogar mich als Anfäger verwundert 😃

    DirkB schrieb:

    eule_123 schrieb:

    muss ich doch die llistel kette global erzeugen mit nem Wertebereich oder?

    Nein.

    eule_123 schrieb:

    Oder übersehe ich dass man die Liste erzeugen kann ohne kette zu erstellen?

    Ja.
    Das nennt sich dynamischer Speicher und wird in C++ mit new und delete erledigt bzw. auch nicht mehr, weils ja std::vector gibt.

    Ich danke dir, hab jetzt mit new und delete gearbeitet und sieht passabel aus. Bzw. es funktioniert , toll ist es bestimmt nicht 🙄

    #include <iostream>
    
    using namespace std;
    
    struct llistel
    {
        float data;
        struct llistel *next;
    };
    
    struct llist
    {
        struct llistel *first;
        int size;
    };
    
    struct llistel kette[50];
    
    //void llistaddfront (struct llist* pllist, float fval){}                   //Funktion soll am Listenkopf ein Listenelemnt mit dem übergebenen float Wert einfügen
    
    void llistcreatefront (struct llist* pllist, int num)                       // Funktion soll eine List mit aAnzahl von num Werten erstellen, Werte aufsteiugend Zahlen von 0
    {
    
        llistel *node;
    
        for (int i = (num-1); i >= 0; i--)
        {
            llistel *node = new llistel;
            node->data = i;
            node->next = (*pllist).first;
            (*pllist).first = node;
            (*pllist).size = (*pllist).size +1;
        }
    
     }
    
    void llistprint (struct llist* pllist)                                      // Die Funktion soll alle Listenelemente auf den Monitor ausgeben
    {
        llistel *old;
        while((*pllist).first)
        {
            cout << "Value:" << (*pllist).first -> data << endl;
            old = (*pllist).first;
            (*pllist).first = (*pllist).first -> next;
            delete old;
        }
    
    }
    
    int main()
    {
        llist llistvar;
    
        llistvar.size=0;
        llistvar.first=NULL;
    
        llistcreatefront(&llistvar,10);
    
        llistprint(&llistvar);
    
        return 0;
    }
    


  • Hallo,
    nächste Aufgabe, nächste Frage 😃

    Ich wollte jetzt ne doppelt verkettete Liste daraus machen. Im Grunde muss ich ja nur einen Pointer hinzufügen.

    void llistcreatefront (struct llist* pllist, int num)                       // Funktion soll eine List mit aAnzahl von num Werten erstellen, Werte aufsteiugend Zahlen von 0
    {
        for (int i = (num-1); i >= 0; i--)
        {
            llistel *node = new llistel; //0
            node->data = i; //1
            node->next = (*pllist).first; //2
            //3
            (*pllist).first = node; //4
            (*pllist).size = (*pllist).size +1;
        }
    }
    

    Nach meinem Verständnis läuft das ganze ja so ab.
    Ich erschaffe bei //0 einen neuen Knoten, bei //1 beschreib ich ihn mit ner Zahl, bei //2 setz ich next auf meinen vorgänger und bei //4 verschieb ich meinen startpunkt auf meinen neuen Knoten, sodass ich mit dem ender der for schleife meinen Startpointer auf meinen letzten erschaffenen Knoten hab.
    So und ich wollte bei //3 meinen prev pointer auf meinen nächsten Knoten zeigen lassen. Aber was ich auch probier, ich krieg immer nen Segmentation Fault.

    Meine Idee bei //3 war

    (*pllist).first -> prev = node;
    

    Steh ich am Schlauch? 🙄



  • Du musst deine llistel struct umbenennen in doubly_linked_node und einen zweiten Zeiger spendiern. Dann hast du einen Zeiger prev, und einen Zeiger next.



  • out schrieb:

    Du musst deine llistel struct umbenennen in doubly_linked_node und einen zweiten Zeiger spendiern. Dann hast du einen Zeiger prev, und einen Zeiger next.

    Das hab ich schon ja 🙂

    struct llistel
    {
        float data;
        struct llistel *next;
        struct llistel *prev;
    };
    


  • Ok. Dann erstellst du ein list-Objekt und dann erstellst du ein list-Node (prev=next=nullptr).
    Dann setzt du deinen first-Zeiger auf das Node-Objekt und machst size=1.
    Dann erstellst du noch ein list-Node (prev=erste-Node und next=nullptr)



  • Hallo,

    eule_123 schrieb:

    manni66 schrieb:

    Du lernst gerade C mit cout.
    Wenn das

    void llistcreatefront (struct llist* pllist, int num)
    

    genau so vorgegeben ist, beherrscht der Aufgabensteller auch kein C++: das struct ist dort, wie auch noch an anderen Stellen in deinem Programm, in C++ überflüssig.

    Das ist so angegeben ja und hat sogar mich als Anfäger verwundert 😃

    Also Du weißt, dass Du da kein C++ sondern wenn überhaupt C lernst! Und wie heißt der Kurs/Vorlesung den/die Du belegt hast?

    Falls der Kurs u.a. das Wort C++ im Titel führt, so biete dem Prof doch mal die angehängte Code-Variante als Lösung an - und erzähle uns dann, wie er reagiert. Wir sind da ganz gespannt! 🕶

    Gruß
    Werner

    #include <iostream>
    
    struct llist
    {
        llist()
            : head_( nullptr )
            , size_( 0 )
        {}
        ~llist()
        {
            for( ; head_; )
            {
                llistel* tmp = head_;
                head_ = head_->next_;
                delete tmp;
            }
        }
    
        void push_front( float d )
        {
            head_ = new llistel( d, head_ );
            ++size_;
        }
    
        friend std::ostream& operator<<( std::ostream& out, const llist& l )
        {
            for( auto p = l.head_; p; p = p->next_ )
                out << p->data_ << " ";
            return out;
        }
    
    private:
        llist( const llist& )  = delete;
        llist& operator=( const llist& )  = delete;
    
        struct llistel
        {
            llistel( float d, llistel* next )
                : data_( d ), next_( next )
            {}
            float data_;
            llistel* next_;
        };
    
        llistel* head_;
        std::size_t size_;
    };
    
    void llistcreatefront( llist* pllist, int num )
    {
        while( --num >= 0 )
            pllist->push_front( float(num) );
    }
    void llistprint( llist* pllist )
    {
        std::cout << *pllist << std::endl;
    }
    
    int main()
    {
        using namespace std;
    
        for( int num; cout << "Size: ", cin >> num; )
        {
            llist l;
            llistcreatefront( &l, num );
            llistprint( &l );
        }
        return 0;
    }
    

    PS.: ich hoffe der Code compiliert bei Dir. Falls nicht , so meld' Dich bitte nochmal.



  • Ich glaube meine Augen sind kaputt. Ich sehe nur noch kleine 'l' überall 😉


Anmelden zum Antworten