Liste vorheriges Element



  • Hallo,
    versuche gerade eine Liste von Personen zu erzeugen. Die Struct enthält einen next- und einen prev-Zeiger , welche auf das vorherige und das nachfolgende Elemnet zeigt.[code="cpp"]
    person* gen_person() {
    person* temp = new person;
    temp->name="";
    temp->gebtag=0;
    temp->gebmon=0;
    temp->gebjar=0;
    temp->next=NULL;
    temp->prev=NULL;
    return(temp);
    }
    for (int i=1; i<ANZAHL; i++) {
    temp->next=gen_person();
    temp=temp->next;
    temp->name=list_name[i];
    temp->gebtag=list_gebtag[i];
    temp->gebmon=list_gebmon[i];
    temp->gebjar=list_gebjar[i];

    }

    for (int i=ANZAHL-1;i>-1;i--} {
    temp2->prev=gen_person();
    temp2=temp2->prev;
    temp2->name=list_name[i];
    temp2->gebtag=list_gebtag[i];
    temp2->gebmon=list_gebmon[i];
    temp2->gebjar=list_gebjar[i];
    }

    Das Problem ist nun, dass next funktioniert, aber prev bei fast allen Einträgen Null ist.



  • Hi,

    du zeigst uns nicht den ganzen Code, so wird es schwer dir wirklich zu helfen.

    Wie erstellst du temp und temp2?

    Normalerweise willst du für prev kein neues Objekt anlegen, sondern sowas machen:

    auto root = gen_person();
    auto succ = gen_person();
    root->next = succ;
    succ->prev = root;
    


  • [code="cpp"#include <stdio.h>
    #include <stdlib.h>
    #include <inttypes.h>
    #include <iostream>
    #include <string>

    using namespace std;

    // Datenstruktur
    struct person {
    string name;
    uint16_t gebtag; // uint16_t = unsigned int mit 16 Bit
    uint16_t gebmon;
    uint16_t gebjar;
    person* next;
    person* prev;
    };

    // Zeiger auf den Listenanfang und auf
    // das durchlaufende aktuelle Element
    person* root;
    person* run;
    person* ENDE;
    // Einige (nach Geburtsjahr sortierte) Vorabeinträge für die Liste
    #define ANZAHL 6
    string list_name[ANZAHL] = {"JHVH", "Konrad Zuse","Tim OReilly","Bill Gates","Mark Zuckerberg","Michel de Notredame"};
    uint16_t list_gebtag[ANZAHL] = {1,22,06,28,14,31};
    uint16_t list_gebmon[ANZAHL] = {1,06,06,10,5,12};
    uint16_t list_gebjar[ANZAHL] = {0,1910,1954,1955,1984,3600};

    // Liefert eine leere Datenstruktur zurück
    person* gen_person() {
    person* temp = new person;
    temp->name="";
    temp->gebtag=0;
    temp->gebmon=0;
    temp->gebjar=0;
    temp->next=NULL;
    temp->prev=NULL;
    return(temp);
    }

    // Erzeugt aus den Vorabdaten eine Liste
    int init_list() {
    person* temp = gen_person();

    root = temp;
    root->name=list_name[0];
    root->gebtag=list_gebtag[0];
    root->gebmon=list_gebmon[0];
    root->gebjar=list_gebjar[0];

    for (int i=1; i<ANZAHL; i++) {
    temp->next=gen_person();
    temp=temp->next;
    temp->prev=gen_person();
    temp->name=list_name[i];
    temp->gebtag=list_gebtag[i];
    temp->gebmon=list_gebmon[i];
    temp->gebjar=list_gebjar[i];
    temp->prev->name=list_name[i-1];
    temp->prev->gebtag=list_gebtag[i-1];
    temp->prev->gebmon=list_gebmon[i-1];
    temp->prev->gebjar=list_gebjar[i-1];
    temp->prev->prev=gen_person();
    temp->prev->prev->name=list_name[i-2];
    temp->prev->prev->gebtag=list_gebtag[i-2];
    temp->prev->prev->gebmon=list_gebmon[i-2];
    temp->prev->prev->gebjar=list_gebjar[i-2];
    }
    }

    /*for (int i=ANZAHL-1;i>-1;i--) {
    temp2->prev=gen_person();
    temp2=temp2->prev;
    temp2->name=list_name[i];
    temp2->gebtag=list_gebtag[i];
    temp2->gebmon=list_gebmon[i];
    temp2->gebjar=list_gebjar[i];

    }*/

    // Formatierte Ausgabe der Daten in der Datenstruktur start
    int print_person(person* start) {
    printf("%02d.%02d.%04d ",start->gebtag,start->gebmon,start->gebjar);
    cout << start->name << endl;
    }

    // Hangelt sich entlang der Liste und gibt alle Einträge aus
    int print_list() {
    cout << "============================\n";

    run = root;
    print_person(run);

    while (run->next!=NULL) {
    run=run->next;
    print_person(run);
    }
    cout << "============================\n";
    }

    // Hangelt sich rückwärts und gibt alle Einträge aus
    int printr_list(person* a ) {
    cout << "***************************\n";
    run = a;
    print_person(run);
    int k=5;
    while (run->prev!=0){
    run=run->prev;
    print_person(run);
    }

    cout <<"****************************\n";
    }
    // Fügt eine Person an der richtigen Stelle ein
    int add_person() {
    string nname,vorname,nachname;
    uint16_t ngebjar;
    uint16_t ngebtag;
    uint16_t ngebmon;

    cout << "Vorname ('-' zum Beenden): ";
    cin >> vorname;
    if (vorname=="-") return(0);
    cout << "Nachname: ";
    cin >> nachname;
    nname = vorname + " " + nachname;
    cout << "Jahr: ";
    cin >> ngebjar;
    //cout << "Geburtsmonat: ";
    //cin >> ngebmon;
    //cout << "Tag: ";
    //cin >> ngebtag;

    run = root;
    while (!(run->gebjar<=ngebjar && run->next->gebjar>=ngebjar)) {
    run=run->next;
    }

    person* temp = gen_person();
    temp->name = nname;
    temp->gebjar = ngebjar;
    temp->next = run->next;
    run->next = temp;
    }

    int rem_person() {
    string nname,vorname,nachname;

    cout << "============ Delete entry ================\n";
    cout << "Vorname: ";
    cin >> vorname;
    cout << "Nachname: ";
    cin >> nachname;
    nname = vorname + " " + nachname;

    run = root;
    while (run->next!=NULL && run->next->name!=nname)
    run=run->next;

    person* temp = run->next;

    run->next = NULL;
    if (temp->next != NULL)
    run->next = temp->next;

    delete temp;
    }

    int alterals_person(){
    string dername,vorname,nachname;

    cout << "Geben sie eine Person an und alle älteren Personen aus der Liste werden ausgegeben\n";
    cout << "Vorname: ";
    cin >> vorname;
    cout << "Nachname: ";
    cin >> nachname;
    dername = vorname + " " + nachname;
    run = root;

    while (run->next->name!=dername) {
    run=run->next;
    }
    printr_list(run);

    }
    int main() {
    int i=0;
    init_list();
    print_list();
    while (add_person()) {};
    print_list();
    //rem_person();
    print_list();
    alterals_person();

    }]
    Eigentlich will ich sowas ohne soviele prevs zu benutzen.
    ps: wie schreibt man hier code


  • Mod

    Du baust deine Liste völlig verkehrt auf. Du erzeugst jedes Mal neue Knoten, wenn du deine next und prev setzt! Die Idee ist doch, dass der alte Knoten auf den neuen zeigt (über das next des alten Knoten) und der neue auf den alten (über das prev des neuen Knoten).

    Daher Algorithmus zum Erstellen eines neuen Knotens:
    -Zeiger auf alten Knoten merken
    -Neuen Knoten erzeugen, Zeiger darauf merken
    -Im alten Knoten next auf den neuen Knoten setzen
    -Im neuen Knoten prev auf den alten Knoten setzen
    -Sonstige Werte im neuen Knoten setzen

    Die Reihenfolge ist dabei relativ beliebig.

    Dem ganzen könnte sehr, sehr geholfen werden, wenn du eine stärkere Kapselung durchführen würdest. Ein Design mit Klassen wäre wesentlich besser, aber wenn das nicht sein soll, dann wenigstens stärker objektorientiert gedacht. Bestes Beispiel und auch gleich die Stelle, an der es hakt, ist das Erzeugen eines neuen Knotens. Bis dieser vollständig einsatzbereit ist, muss Code von mindestens drei verschiedenen Stellen des Programms ausgeführt werden. Und du hast an mehreren Stellen Wiederholungen dieser Codeteile. Kein Wunder, dass da leicht etwas schief geht. Das sollte eine einzige, klar abgegrenzte Funktion sein, die genau diese Aufgabe ausführt, dies vollständig und richtig tut, und sonst nichts. Ebenso für alle andere Funktionalität deiner Liste.



  • DERHONK schrieb:

    ps: wie schreibt man hier code

    Code markieren und dann auf "C++" clicken (neben "Code" unter dem Textfeld)


Log in to reply