sortiertes Einfügen in Liste



  • Hallo,
    wir sollen eine Belegarbeit zum Thema verkettete Listen Schreiben. Einmal einfach Verkettete und dann doppelte. Das Programm soll, ein Listenelement generieren können, ein Element am Anfang einer spezifizierten Liste einfügen, ein Element einfügen am Ende, einfügen vor nächst kleinerem Element(hier versteh ich selbst nicht was er da von uns will aber egal).
    Ich bin jetzt so weit das mein Programm ein Element am Ende der einfach verketteten Liste anhängen kann und ein Element nach Eingabe eines Namens löscht.

    #include "stdio.h"
    #include "string.h"  
    #include "time.h"
    #include "stdlib.h"
    
    struct person {         /* deklariert den Strukturtyp person */
        int   alter, kdnr;
        float gewicht;
        char  name[25];
        char nname[25];
       struct person*next;
      };
    struct person* first;  
    
    //------------Funktionen----------------
    void anhang( int alter,float gewicht, char name[],char nname[]);
    void Ausgeben();
    void Loeschen(char name[]);
    
    int main ()
    {
     char name[25];
     int c=0;
     char nname[25];
     int alter,i; 
     float gewicht;
    char a, b;
    
    anhang(43,80.47,"Max", "Mustermann");
    anhang(54,78,"Blah", "Blahblah");
    while (c==0){
    printf ("Moechten Sie machen?\n"); 
    printf ("(1)Daten eingeben\n(2)Daten Loeschen\n(3)Programm beenden\n");
    scanf("%i",&c); 
    while (c!=1&&c!=2&&c!=3&&c!=4){
    printf ("falsche Eingabe: ");
    scanf("%i",&c);
    }
    if (c==3)break;
    if (c==1)  {    
    printf ("Vorname: ");
    scanf ("%24s",name);
    fflush(stdin);
    printf ("Nachname: ");
    scanf("%24s",nname);
    printf ("Alter: ");
    scanf ("%i",&alter);
    printf ("Gewicht: ");
    scanf ("%f",&gewicht);
    anhang(alter,gewicht,name, nname);
    Ausgeben();
    c=0;
    }
    if (c==2){
               printf("Bitte Namen eingeben: ");
               scanf ("%24s",name);
               Loeschen (name);
               Ausgeben();
               c=0;
               }
    }
    
    } 
    //---------------------------Anhängenfunktion-----------------------------------
    void anhang(int alter,float gewicht, char name[],char nname[]){
         struct person* ptr;
    
            if( first == NULL )
            {
               first = malloc( sizeof( *first ) );
    
              strcpy( first->name, name);
              strcpy (first->nname, nname);
              first->alter = alter;
              first->gewicht= gewicht;
              first->next = NULL;
            }
    
            else
            {
               ptr = first;
    
               while(ptr->next != NULL)
                  ptr = ptr->next;
    
               ptr->next = malloc(sizeof( *ptr ));
    
              ptr = ptr->next;
              strcpy( ptr->name, name);
              strcpy (ptr->nname, nname);
              ptr->gewicht= gewicht;
              ptr->alter = alter;
    
              ptr->next = NULL;
           }
         }
    //----------------------------Ausgabefunktion-----------------------------------
     void Ausgeben()
          {
             struct person* ptr;
         int i=1;
             ptr = first;
    
             while( ptr != NULL )
            {
            printf ("----------Liste %i----------\n",i);        
            printf( "Name: %s %s\nAlter: %i\nGewicht: %0.2fkg \n",ptr->name,ptr->nname,ptr->alter,ptr->gewicht);
            printf("\n");
            ptr = ptr->next;
               i++;
            }
    
         }
    
    //-----------------------------Löschfunktion------------------------------------
      void Loeschen(char name[])
        {
    
        struct person* ptr, * ptrA;
    
            if( first != NULL )
            {
               if( strcmp( first->name, name ) == 0 )
    
               {
                  ptr = first->next;
    
                  free(first);
    
                  first = ptr;
               }
    
               else
               {
                  ptr = first;
    
                 while( ptr->next != NULL )
                 {
    
                    ptrA = ptr->next;
                    if( strcmp( ptrA->name, name ) == 0 )
    
                    {
                       ptr->next = ptrA->next;
                       free( ptrA );
    
                       break;
                    }
    
                    ptr = ptrA;
                 }
              }
           }
        }
    

    Jetzt möchte ich dass das Programm neue Elemente nach Namen sortiert einfügt.
    Studiere nebenbei gesagt Elektrotechnik bin also nicht der große Informatiker.^^
    Wir dürfen Code aus anderen Quellen (Bücher, Netz) kopieren.

    Hab jetzt dieses Programm gefunden welches sowas im Ansatz kann. Kann es aber nicht auf mein Programm zuschneiden.

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    
    typedef struct node Node; 
    
    struct node 
    { 
        char *name; 
        Node *next; 
    }; 
    
    Node* new_node() 
    { 
        return calloc ( 2, sizeof ( Node ) ); 
    } 
    
    void show ( Node* a ) 
    { 
        while ( a ) 
            printf ( " %s", a->name ), a = a->next; 
            printf ( "\n");
    } 
    
    Node* insert ( Node* a, Node* b ) 
    { 
        Node* first = a, *c = NULL; 
        if ( a == NULL ) return b; 
        while  ( a && strcmp (a->name, b->name ) < 0 ) 
            c = a, a = a->next; 
        if ( a && !c ) b->next = a, first = b; 
        else c->next = b, b->next = a; 
        return first; 
    } 
    
    void free_list ( Node* a ) 
    { 
        Node* b = a; 
        while ( b ) 
            b = b->next, free ( a ), a = b; 
    } 
    
    enum {argc = 4}; 
    
    int main() 
    { 
        int i = 0; 
        char* argv[argc] = { "j", "o", "b", "h"  }; 
        char a, b, c; 
    
        Node* first = NULL, *new = NULL; 
    
        while ( i < argc ) 
        { 
            if ( NULL == ( new = new_node() )) break; 
            new->name = argv[i++]; 
            first = insert ( first, new ); 
        } 
    
        show ( first ); 
        free_list ( first ); 
    system("PAUSE");
        return 0;
    

    Bin für jede Hilfe und jeden Vorschlag dankbar.

    lg



  • Das sieht doch schon gut aus, dein bisheriger Code ist zwar etwas holprig, sollte aber erstmal funktionieren (habe nicht compiliert).
    Wenn du jetzt noch

    typedef struct person Node;
    

    hinzufügst und in insert name durch nname ersetzt, sollte deine Aufgabe bloß noch darin bestehen, insert richtig aufzurufen.
    insert sucht vom Beginn der Liste und stoppt beim ersten Element, wo nname größergleich als dein neu einzufügender nname ist und fügt dann dein neues Element vor diesem gefundenen Element in die Liste ein. Die Liste darf aber nicht leer sein. Rückgegeben wird von insert ein Zeiger auf das 1. Element deiner Liste.
    Vielleicht solltest du den Fall der leeren Liste innerhalb von insert noch implementieren, ist aber einfach, die Funktion dafür hast du schon.
    Kennst du switch/case? Würde der Struktur deines Programms guttun.



  • klappt das so 😕

    typedef struct _list{
      struct _list *next;
    }list;
    
    typedef struct _list_head{
      list *first;
      list *last;
    }list_head;
    
    void list_unshift(list_head *head,list *node){
      list *buffer = head->first;
      if(buffer)
        node->next = buffer;
      else
        head->last = node;
      head->first = node;
    }
    
    void list_push(list_head *head,list *node){
      list *buffer = head->last;
      if(buffer)
        buffer->next = node;
      else
        head->first = node;
      head->last = node;
    }
    

    @edit: 😮 voll buggy



  • btw. wenn ich noch einmal ne einfach verkettete liste sehe wo sich derjenige das letzte element nicht merkt dann 😡

    @edit natürlich nur wenn er am ende einfügen will 😉



  • Danke für die Hilfe.
    Ich hab jetzt einfach diesen Teil:

    Node* insert ( Node* a, Node* b ) 
    { 
        Node* first = a, *c = NULL; 
        if ( a == NULL ) return b; 
        while  ( a && strcmp (a->nname, b->nname ) < 0 ) 
            c = a, a = a->next; 
        if ( a && !c ) b->next = a, first = b; 
        else c->next = b, b->next = a; 
        return first; 
    }
    

    in das eigentliche Programm kopiert. Dann noch

    typedef struct person Node;
    

    gemacht. Ich scheitere jetzt nur noch daran was für werte ich beim Funktionsaufruf übergeben soll. Ich hab es mit insert (first,nname) versucht was aber nicht geht und sicherlich auch unsinn ist. 😕



  • Genau das habe ich vorausgesehen, deshalb schrieb ich oben:

    sollte deine Aufgabe bloß noch darin bestehen, insert richtig aufzurufen.

    und prompt stellst du die Frage. Ich bin der Meinung, hier solltest du mal allein weitermachen.



  • Hast ja recht. 🙂
    Etwas Eigenleistung sollte ich schon noch erbringen. Werd mich mit den anderen aus meiner Gruppe noch beraten. Mal sehen was die dazu sagen.
    Trotzdem danke für die Hilfe.


Anmelden zum Antworten