Listen element einfügen



  • Habe ein Programm erstellt dass mir ein Listenelement in sortierter Reihenfolge einfügen soll, doch leider gibt mein Compiler auußer dem cout<< nichts aus. Leider finde ich einfach nicht den Fehler woran es liegen könnte. Wäre toll wenn mir hier jemand helfen könnte 🙂

    hier mein code:

    #include <iostream>
    
    using namespace std;
    
    struct lelem
    {
        int data;
        lelem *next;
    };
    
    void print(lelem *head)
    {
        lelem *pelem=head;
        while (pelem!=0)
        {
            cout << pelem->data << endl;
            pelem=pelem->next;
        }
        cout << "\n"<<endl;
    }
    
    void insert_front(lelem *head, int d)
    {
        lelem *newhead=new lelem;
        newhead->data=d;
        newhead->next=head;
        head=newhead;
    }
    void insert_sorted(lelem *&head, int d) //fügt ein Elemenet sortiert in die Liste ein (d.h wenn Liste davor sortiert war ist sie danach wieder sortiert
    {
       if (head==0 || d < head->data)          // wenn Liste leer oder schon das erste Element größer ist als das einzufügende
       {
           insert_front(head,d);              // dann am anfang der Liste einfügen
           return;
       }
                        //neuer Zeiger zum durchlaufen der Liste, soll am ENde auf das ELement zeigen hinter dem eingefügt wird
    else
    {  lelem *temp =head;
    
       while (temp->next !=0 && d>=temp->next->data) //So lange nicht am Ender der Liste angekommen und nächstes Element kleiner als das einzufügende
       {
           temp=temp->next;                 //zum nächsten Element gehen
       }
       lelem *neu=new lelem;                //neues Element hinter temp einfügem //neuen Speicher für neues Element anfordern
       neu->data=d;                        // Datenfeld des neuen Elements schreiben
       neu->next=temp->next;
       temp->next=neu;
    }
    
    }
    
    int main()
    {
        lelem*head=NULL;
    
        cout << "Testen von insert_sorted:\n"<<endl;
    
        insert_sorted(head,5);
        insert_sorted(head,7);
        insert_sorted(head,3);
        insert_sorted(head,9);
        insert_sorted(head,10);
        print(head);
    
        return 0;
    }
    

    Mod-Edit Arcoth: Code-Tags.


  • Mod

    void insert_sorted(lelem *&head, int d) //fügt ein Elemenet sortiert in die Liste ein (d.h wenn Liste davor sortiert war ist sie danach wieder sortiert 
    { 
       if (head==0 || d < head->data)          // wenn Liste leer oder schon das erste Element größer ist als das einzufügende 
       { 
           insert_front(head,d);              // dann am anfang der Liste einfügen 
           return; 
       }
    

    Der erste Aufruf an insert_sorted fällt offensichtlich in diesen Zweig. Allerdings nimmt insert_front keine Referenz. D.h. nach dem ersten Aufruf von insert_sorted zeigt das head aus main nach wie vor auf NULL . Das wiederholt sich bei den nächsten Aufrufen. head ist also auch bei deinem Aufruf an print NULL .


  • Mod

    Eleganter lässt sich das Ganze formulieren, wenn du nicht über Listenelement iterierst, sondern über Zeiger, die auf das nächste Listenelemente zeigen. Dann verschwindet der Sonderfall des Listenanfangs, denn head ist ja auch so ein Zeiger.

    void insert_sorted(lelem*& head, int d)
    {
       lelem** current = &head;
    
       while (*current != nullptr && (*current)->data < d)
       {
           current = &(*current)->next; // zum Zeiger auf das übernächste Element gehen
       }
       *current = new lelem{d, *current};
    }
    

    Oder umgekehrt, ist ja jeder next Zeiger im Grunde so etwas wie der Anfang einer Teilliste, folglich könnte man auch schreiben:

    void insert_front(lelem*& head, int d)
    {
        head = new lelem{d, head};
    }
    void insert_sorted(lelem*& head, int d)
    {
       if (head == nullptr || d <= head->data)
       {
           insert_front(head, d);
       }
       else
       {
           insert_sorted(head->next, d);
       }
    }
    

    Ist nat. u.U. keine gute Idee, da die Rekursion zum Stacküberlauf führen könnte.



  • Danke camper für deinen code! bekomme jetzt zwar eine Ausgabe aber mir wird jede Zahl doppelt ausgegeben 😕


  • Mod

    Ich habe keine Ahnung, was du falsch machst.
    http://ideone.com/Sd39GI



  • camper schrieb:

    void insert_front(lelem*& head, int d)
    {
        head = new lelem{d, head};
    }
    void insert_sorted(lelem*& head, int d)
    {
       if (head == nullptr || d <= head->data)
       {
           insert_front(head, d);
       }
       else
       {
           insert_sorted(head->next, d);
       }
    }
    

    Ist nat. u.U. keine gute Idee, da die Rekursion zum Stacküberlauf führen könnte.

    Das ist triviale Tailrekursion?


  • Mod

    schwanz schrieb:

    camper schrieb:

    void insert_front(lelem*& head, int d)
    {
        head = new lelem{d, head};
    }
    void insert_sorted(lelem*& head, int d)
    {
       if (head == nullptr || d <= head->data)
       {
           insert_front(head, d);
       }
       else
       {
           insert_sorted(head->next, d);
       }
    }
    

    Ist nat. u.U. keine gute Idee, da die Rekursion zum Stacküberlauf führen könnte.

    Das ist triviale Tailrekursion?

    Richtig. Allerdings verlangt der Standard nicht, dass das optimiert wird. Gelegentlich wird Software ja auch zwecks Fehlerfindens gar nicht optimiert.


Anmelden zum Antworten