Mischen von Einträgen einer doppelt verketteten Liste

Tutorials.at
Verfügbare Informationen zu "Mischen von Einträgen einer doppelt verketteten Liste"

  • Qualität des Beitrags: 0 Sterne
  • Beteiligte Poster: Zuul - exbs - DrPhil_Guth
  • Forum: Tutorials.at
  • Forenbeschreibung: Programmierforum
  • aus dem Unterforum: C / C++
  • Antworten: 11
  • Forum gestartet am: Mittwoch 19.04.2006
  • Sprache: deutsch
  • Link zum Originaltopic: Mischen von Einträgen einer doppelt verketteten Liste
  • Letzte Antwort: vor 17 Jahren, 5 Tagen, 16 Stunden, 49 Minuten
  • Alle Beiträge und Antworten zu "Mischen von Einträgen einer doppelt verketteten Liste"

    Re: Mischen von Einträgen einer doppelt verketteten Liste

    Zuul - 21.03.2007, 10:44

    Mischen von Einträgen einer doppelt verketteten Liste
    Hey meine lieben :)


    Edited:
    ---------------
    Nachdem ich natürlich auch ned still rum sitz, hab ich das problem mit de verschlucken des erstn buchstabn schon gelöst ... allerdings könntet ihr mir bei folgendem problem helfen ...


    ich hab eine verkettete liste die geshuffled werden muss ... ( also die zeilen der datei solln an irgnd einer und ned der jeweiligen position der datei stehn )

    ich tu mir bissl schwer mir das vorstelln zu können ... ein kollege meinte man müsse das gleich beim einlesen machen ... allerdings hab ich keine ahnung wie ich JEDE zeile der datei in je eine position der liste krieg, die allerdings NICHT geordnet is !

    ideen? .... completter source des beispiels folgt .... btw. zu starten wie folgt

    v2.exe (-repeat) (-random) tracklist.txt

    ausgeklammerte parameter sind optional .... tracklist ist ein datei in der tracks stehn, Tite<tabulator>Interpret<tabulator><Album>


    ------REEDITED---------

    So ich hatte folgenden Gedankengang:

    ich vertausche einfach benachbarte elemente ... die häufigkeit der vertauschungen sollte dann zufällig sein, damit die liste immer anders "gemischt" ist ... zu diesem zweck hab ich mir diverse skizzen und um-link-pläne gemacht dei wie folgt aussahen :

    l1 - l2 - l3 - l4
    double linked

    l3->next->prev = l2;
    l2->prev->next = l3;
    l3->prev = l2->prev;
    l2->next = l3->next;
    l3->next = l2;
    l2->prev = l3;

    ich hab das dann auf mein programm umgemünzt was dann wie folgt aussieht:

    helpnext=track->next;

    helpnext->next->prev = track;
    track->prev->next = helpnext;
    helpnext->prev = track->prev;
    track->next = helpnext->next;
    helpnext->next = track;
    track->prev = helpnext;



    hab allerdings diverse fehler ... wenn ich die funktion gleich zu begin aufrufe bekomme ich einen speicherfehler ( nicht weiter verwunderlich, da die abfrauge auf prev==NULL noch fehlt ) .. wenn ich mitten in der liste die funktion aufrufe bekomme ich merkwürdige sonderzeichen...

    frage, ist die "vorgehensweise" korrekt? .. worin besteht der offensichtlich vorhandene fehler ? ...

    code wurde aktualisiert



    viel spaß beim tüfteln

    u.a.w.g.
    Zuul

    Code: #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <conio.h>
    #include <time.h>

    typedef struct s_liste
    {
       char *titel;
       struct s_liste *next;
       struct s_liste *prev;

    }   t_liste;

    t_liste *dateilesen(char *pfad);                                 //FKT Prototypen
    t_liste *play(t_liste *track);                                                   
    t_liste *rando(t_liste *track);
    t_liste *prevtrack(t_liste *track);
    t_liste *followtrack(t_liste *track);
    t_liste *rft(t_liste *track);
    t_liste *killall(t_liste *track);   

    int counter=0;
    t_liste *dateilesen(char *pfad)
    {
       FILE *datei;
       char zwischen[250];
       t_liste  *current,*following, *head;

       
       datei=fopen(pfad,"r");
       

       current=(t_liste*)malloc(sizeof(t_liste));      // speicherplatz reservieren
       head=current;
       current->next=NULL;                        // nächster zeiger zeigt derzeit auf nichts
       current->prev=NULL;                        // zeiger kann noch auf keinen vorhergehenden Track zeigen
       

       if(datei==NULL)
       {
          printf("Fehler beim lesen der Datei");      //Testen ob datei Geladen wurde   
          return 0;
       }
       else
       {
          while(fgets(zwischen,250,datei))
          {
             if(counter==0)
             {
                fgets(zwischen,250,datei);                     // datei-header übergehen
             }
             {
             current->titel=strdup(zwischen);                  //Aktuelle Zeile in Current-Titel kopieren
             following=(t_liste*)malloc(sizeof(t_liste));         // für den folgenden titel speicher reservieren
             following->prev=current ;                        // den Folgenden zeiger der zürück zeigt auf den momentan Track zeigen lassen
             current->next=following;                        // den Zeiger der vor zeigt auf den folgenden Track zeigen lassen
             current=following;                              // den momentanen Track durch den Folgenden Ersetzen.
             following->next=NULL;                           // der folgezeiger des Nächsten Tracks existiert noch nicht.
             counter++;         
             }
          }
       }   
       fprintf(stdout,"Die Tracklist beinhaltet %d Tracks\n",counter);
       fclose(datei);
       return head;
    }

    t_liste *play(t_liste *track)
    {
       printf("Momentaner Track: %s", *track);                        // Ausgabe des gewählten Titels
       track=track->next;
       return(track);
    }

    t_liste *killall(t_liste *track)                              // Allocierten Speicherbereich wieder frei geben
    {
       t_liste *help;

       while(track->next!=NULL)
       {
          track=track->next;     
       }   
       while(help!=NULL)
       {
          help=track->prev;
          free(track);
          track=help;
       }
       return EXIT_SUCCESS;
    }

    t_liste *prevtrack(t_liste *track)
    {

       if(track->prev==NULL)                                 // Zeigt der Nächste Track auf NULL ist die Liste durchgearbeitet
       {
          fprintf(stdout,"Es gibt keinen vorhergehenden Titel. Aktueller wird wiederholt. \n");
          return track;
       }
       else                                   
       {
          track=play(track->prev);
          return track->prev;                                 // Der Nächste Track wird returned
       }
    }


    t_liste *rft(t_liste *track)                              // rft gibt folgenden titel aus
    {
       if(track->next==NULL)
       {
          fprintf(stdout,"Es gibt keinen folgenden Titel. Programm wird beendet.\n");
          return EXIT_SUCCESS;
       }
       else
       {
          track=play(track);
          return track;
       }
    }

    t_liste *followtrack(t_liste *track)                        // followtrack löscht vorhergehenden track
    {
       t_liste *help;
       if(track->next==NULL)
       {
          fprintf(stdout,"Es gibt keinen folgenden Titel.Programm wird beendet.\n");
          return EXIT_SUCCESS;
       }
       else
       {   
          help=track;
          track=track->next;
          track->prev=NULL;
          free(help);
          play(track);
          return track;
       }
    }


    t_liste *rando(t_liste *track)
    {
       t_liste *helpnext;

       helpnext=track->next;

       helpnext->next->prev = track;
       track->prev->next = helpnext;
       helpnext->prev = track->prev;
       track->next = helpnext->next;
       helpnext->next = track;
       track->prev = helpnext;


       printf("%s",track);

       return track;
    }


    int main(int argc,char **argv)
    {
       char tastendruck=' ';
       t_liste *start;
       int random=0,repeat=0,i;

       fprintf(stdout,"\n\n\nTracklist-Steuerung V 0.2\n");
       fprintf(stdout,"------------------------------------------------- \n");
       start=dateilesen(argv[argc-1]);   

       for(i=0;i<argc;i++)                     //überprüfen ob repeat oder random gesetzt wurde
       {
          if(strcmp("-random",argv[i])==0)
          {
             random=1;         
             fprintf(stdout,"Player ist im Random-modus!\n");
          }
          if(strcmp("-repeat",argv[i])==0)
          {
             repeat=1;
             fprintf(stdout,"Repeat-modus: Bei vorspulen werden vorangehende Tracks nicht entfernt.\n");
          }
       }
       fprintf(stdout,"------------------------------------------------- \n");
       fprintf(stdout,"Abspielen:\t\tSpace \n");
       fprintf(stdout,"Previous Track: \t  < \n");
       fprintf(stdout,"Next Track:\t \t  > \n");
       fprintf(stdout,"Beenden:\t \t  q \n");

       while(1)
       {
          tastendruck=getch();
         
          switch(tastendruck)
          {
          case 'q': killall(start); return EXIT_SUCCESS;
                   
          case '>': if(repeat==1)
                  {
                     start=rft(start); break;
                  }
                  else
                  {
                     start=followtrack(start); break;
                  }

          case '<': start=prevtrack(start); break;
           
          case 'r': start=rando(start); break; 

          case ' ': start=play(start); break;

          default: fprintf(stdout,"Eingabe nicht korrekt.\n"); break;
          }     
       }
       return EXIT_SUCCESS;
    }



    Re: Mischen von Einträgen einer doppelt verketteten Liste

    exbs - 21.03.2007, 14:14


    ich habe das jetzt nur überflogen, aba damit könntest du recht haben.

    "fgetc" setzt den "dateizeiger" auf das 2te zeichen, weil es ja das erste gelsesn hat ... probier doch mal mit

    Code: fseek(datei, 0, SEEK_SET) ... den zeiger auf anfang zu setzten ...

    [edit]

    oder du versuchst es alternatiev mal mit einer anderen abbruchbedingung für deine while-schleife.

    ich denk da an sowas

    Code: while(!feof(datei))

    [edit2]

    ach ja und wenn du speicher allokierst ... solltest du ihn auch wieder freigeben: Code: free(allokierter_speicher); ... um ihn nicht gebunden an das system zurückzugeben.



    Re: Mischen von Einträgen einer doppelt verketteten Liste

    Zuul - 21.03.2007, 14:29


    danke für die antwort ....

    hast sie wohl geschriebn während ich editiert hab ; )

    wie man sieht hab ich jetz einfach eine andre bedinung in der whileschleife .. jetzt funktionierts wunderbar ;)

    .... das mitm random is mir allerdings immer noch unklar ....

    mfg
    Zuul



    Re: Mischen von Einträgen einer doppelt verketteten Liste

    DrPhil_Guth - 21.03.2007, 16:36


    Wow, sieht nach nem interessantem programm aus. Ist das absichtlich in reinem C, oder bist du geneigt aus dem ganzen C++ werden zu lassen?

    Wenn du es bist, dann kann ich dir folgendes raten:

    Es ist zwar echt toll, dass du eine Verkettete liste schreiben kannst, und damit auch beweist dass du mit zeiger und speicher umgehen kannst. Nur... Jetzt bitte nicht böse sein... Wozu? Es gibt sowas schon vorprogrammiert! Schau mal in irgend einer Dokumentation zur STL, ob du nicht vielleicht sowas wie list findest. Alternativ dazu gibts noch andere coole container.
    Ich sags gleich, die sind eigentlich nicht wirklich kompliziert, ziemlich sicher und vor allem extrem bequem. Da kannst du dann objekte mit insert(), push_front(), push_back() einfügen. Die speicherallokation wird dann vom container selber erledigt. Mit random_shuffle() können die Elemente gemischt werden.
    Alternativ zum list container kannst du auch den vector container verwenden.



    Re: Mischen von Einträgen einer doppelt verketteten Liste

    DrPhil_Guth - 21.03.2007, 16:58


    In klassischem C müsstest du zuerst deine liste shuffeln lassen und dann die einzelnen knoten ausgeben lassen.

    Also als erstes eine zweite liste schaffen, und die dann zufällig vertauschen lassen.
    Vertauschen lassen: einen beliebigen knoten nehmen (ein schleife beliebig oft durchlaufen lassen), einen zweiten beliebigen knoten nehmen, und dann einfach die zeiger next und prev mit den jeweils anderen vertauschen. Das ein paar mal, und dann ein lied nach dem anderen ausgeben lassen. Wenn die lieder aus sind, das ganze nochmal shuffeln.



    Re: Mischen von Einträgen einer doppelt verketteten Liste

    Zuul - 21.03.2007, 18:22


    reines c is pflicht!


    ich bin leider ned so der held was pointer usw angeht .. aber ich werd wohl mal versuchn deinem rat zu folgn

    mfg
    Zuul



    Re: Mischen von Einträgen einer doppelt verketteten Liste

    DrPhil_Guth - 21.03.2007, 19:12


    Gut, wenn du willst... C++ wär da halt wirklich einfacher, aber egal.


    Zuul hat folgendes geschrieben: ich bin leider ned so der held was pointer usw angeht ..
    Deine liste ist echt gut... Respekt! Hast du die selber geschrieben?

    Welchen rat meinst du denn? Den mit der STL oder den mit der Zweiten Liste?



    Re: Mischen von Einträgen einer doppelt verketteten Liste

    Zuul - 21.03.2007, 19:22


    Hey ; )

    nahjo habs schon selbst geschriebn, hatt allerdings unterstützung von einem freund, der mir über internet immer mal wieder gute tipps gab.

    ich wollt an und für sich die zweite liste verwenden ...

    scheint aber als würd ich des ned so ganz hinkriegn ^^ ...

    momentan is meine idee, dass ich ja schon vor und zurück springen kann, ich also nur irgndwie in einer schleife zufällig oft nach vorne/zurück springen muss ... problem is dann natürlich, was mit den datein geschehn, die übergangen werdn ^^ ... das is dann natürlich wieder schlecht :D

    drum steht der betrieb grade :D


    ---edited---
    Siehe Ursprungsbeitrag



    mfg
    Zuul



    Re: Mischen von Einträgen einer doppelt verketteten Liste

    DrPhil_Guth - 21.03.2007, 22:54


    Wieso denn?
    Du hangelst dich einfach von node zu node, vertauscht aber nur die end- nodes.

    so ca.:
    Code:
    for (int i = 0; i <= rand; i++)
    {

        /* Faengt von vorne an, wenn am ende angekommen */
        if (current_first->next == NULL)
        {
            current_first = head;
        }
        else
        {
            current_first = current_first->next;
        }
    }

    /* Das gleiche mit current_second, mit einer anderen zufallszahl */


    /* Jetzt die beiden nodes vertauschen*/
    t_list* temp_node;
    temp_node = (t_list*) malloc (sizeof(t_list));

    temp_node->next = current_first->next;
    temp_node->prev = current_first->prev;

    current_first->next = current_second->next;
    current_first->prev = current_second->prev;

    current_second->next = temp_node->next;
    current_second->prev = temp_node->prev;

       

    Oder so ähnlich...

    ps.: Zum Thema Reines C: In C gibts keine Kommentare mit //, sondern nur mit /* */, aber das nur so nebenbei ;-)


    [edit] pps.: Wenn du was am code änderst, könntest du dann bitte nicht nur den code oben aktualisieren, sondern auch deinen Beitrat editen oder gleich besser nen neuen machen, mit den änderungen? Schließlich sollen andere user auch noch erfahren, was dein ausgangspunkt war. Und vor allem merkt man dann besser ob man nicht umsonst geschrieben hat :evil:



    Re: Mischen von Einträgen einer doppelt verketteten Liste

    Zuul - 22.03.2007, 10:02


    so .. ich hab mal wieder bissl weiter gemacht ...bin allerdings noch ned viel weiter ..

    und damit ihr aufm aktuelln stand seid nochmal der frische code :)

    rando bräuchte dringend hilfe ! ! ! ==> wirft fehler

    mfg
    Zuul

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <conio.h>
    #include <time.h>

    typedef struct s_liste
    {
       char *titel;
       struct s_liste *next;
       struct s_liste *prev;

    }   t_liste;

    t_liste *dateilesen(char *pfad);                                 //FKT Prototypen
    t_liste *rplay(t_liste *track);
    t_liste *rplay(t_liste *track);                                                   
    t_liste *rando(t_liste *track);                  /* später t_liste *rando(char *pfad);   */
    t_liste *prevtrack(t_liste *track);
    t_liste *followtrack(t_liste *track);
    t_liste *rft(t_liste *track);
    t_liste *killall(t_liste *track);   

    int counter=0;
    t_liste *dateilesen(char *pfad)
    {
       FILE *datei;
       char zwischen[250];
       t_liste  *current,*following, *head;

       
       datei=fopen(pfad,"r");
       

       current=(t_liste*)malloc(sizeof(t_liste));      // speicherplatz reservieren
       head=current;
       current->next=NULL;                        // nächster zeiger zeigt derzeit auf nichts
       current->prev=NULL;                        // zeiger kann noch auf keinen vorhergehenden Track zeigen
       

       if(datei==NULL)
       {
          printf("Fehler beim lesen der Datei");      //Testen ob datei Geladen wurde   
          return 0;
       }
       else
       {
          while(fgets(zwischen,250,datei))
          {
             if(counter==0)
             {
                fgets(zwischen,250,datei);                     // datei-header übergehen
             }
             {
             current->titel=strdup(zwischen);                  //Aktuelle Zeile in Current-Titel kopieren
             following=(t_liste*)malloc(sizeof(t_liste));         // für den folgenden titel speicher reservieren
             following->prev=current ;                        // den Folgenden zeiger der zürück zeigt auf den momentan Track zeigen lassen
             current->next=following;                        // den Zeiger der vor zeigt auf den folgenden Track zeigen lassen
             current=following;                              // den momentanen Track durch den Folgenden Ersetzen.
             following->next=NULL;                           // der folgezeiger des Nächsten Tracks existiert noch nicht.
             counter++;         
             }
          }
       }   
       fprintf(stdout,"Die Tracklist beinhaltet %d Tracks\n",counter);
       fclose(datei);
       return head;
    }

    t_liste *play(t_liste *track)
    {
       if(track==NULL)
       {
          fprintf(stdout,"Kein weiterer Track.\n");
          return EXIT_SUCCESS;
       }
       else
       {      
          t_liste *help=track->prev;
             
          fprintf(stdout,"Momentaner Track: %s", *track);                        // Ausgabe des gewählten Titels
          track->prev=NULL;
          free(help);
          return(track);
       }
    }

    t_liste *rplay(t_liste *track)
    {
       if(track==NULL)
       {
          fprintf(stdout,"Kein weiterer Track");      
    //      return(rando(track));                           später Mischen und Neu startetn.
       }
       else
       {
          printf("Momentaner Track: %s", *track);                        // Ausgabe des gewählten Titels
          return(track);
       }
    }


    t_liste *killall(t_liste *track)                              // Allocierten Speicherbereich wieder frei geben
    {
       t_liste *help=NULL;

       while(track->next!=NULL)
       {
          track=track->next;     
       } 
       help=track;
       while(help!=NULL)
       {
          help=track->prev;
          free(track);
          track=help;
       }
       fprintf(stdout,"Das Program wurde beendet.\n");
       return EXIT_SUCCESS;
    }

    t_liste *prevtrack(t_liste *track)
    {
       if(track==NULL||track->prev==NULL)               // Zeigt der Nächste Track auf NULL ist die Liste durchgearbeitet
       {
          fprintf(stdout,"Es gibt keinen vorhergehenden Titel. Aktueller wird wiederholt. \n");
          return track;
       }
       else                                   
       {
          track=rplay(track->prev);
          return track;                                 // Der Nächste Track wird returned
       }
    }


    t_liste *rft(t_liste *track)                              // rft gibt folgenden titel aus
    {
       if(track->next==NULL)
       {
          fprintf(stdout,"Es gibt keinen folgenden Titel. Programm wird beendet.\n");
          return EXIT_SUCCESS;
       }
       else
       {
          track=rplay(track->next);
          return track;
       }
    }

    t_liste *followtrack(t_liste *track)                        // followtrack löscht vorhergehenden track
    {

       if(track->next==NULL)
       {
          fprintf(stdout,"Es gibt keinen folgenden Titel.Programm wird beendet.\n");
          return EXIT_SUCCESS;
       }
       else
       {   
          t_liste *help;
         help=track;
          track=track->next;
          track->prev=NULL;
          free(help);
          rplay(track);
          return track;

       }
    }
                

    t_liste *rando(t_liste *track)            /* Idee wäre, rando statt dateilesen aufzurufen also t_liste *rando(char *pfad) */
    {                                 /* damit die liste gesuffled ist und mit andren Funktionen */
       int size = counter;                  /* direkt angesteuert werden kann.*/
       t_liste *aktuell;
       t_liste *neu = (t_liste*)malloc(sizeof(t_liste));

       

       int zahl =0,i=0,isfirst=1;
       
       srand(time(NULL));                  /* weil nur 1 zufallszahl gebraucht wird zeit dazu verwenden*/
       zahl=((rand()%size))%10+1;            /* 2tes modulo zwecks testen anschaulicher*/

       aktuell=track;                     /* idee: 2te liste machen, dann in erster zufällig nach vorne springen */
       aktuell->next=NULL;                  /* 2te Liste mit den zufällig gewählten elementen befüllen*/
                                     /* 2te Liste ist somit geshuffled und kann dann wie gehabt verwendet werden*/
       printf("track: %s\n ",track->titel);
       printf("Aktuell-Prev: %s\n ",aktuell->prev);
       printf("Aktuell-Next: %s\n ",aktuell->next);

       for(i=1;i<=zahl;i++)
          {
             if(isfirst)
             {
                neu=aktuell;            /* Neue Liste bekommt aktuellen wert zugewiesen */
                neu->prev=NULL;            /* Erstes element hat weder prev noch next element */
                neu->next=NULL;
                isfirst=0;               /* ist nicht mehr erstes element */         
                
                printf("Bin im Random-If\n");
                printf("Neu-if: %s\n ",neu);
                printf("Neu-Prev-if: %s\n ",neu->prev);
                printf("Neu-Next-if: %s\n ",neu->next);

             }
             else
             {
                neu->next = aktuell;      /* Folgeelement der Liste bekommt aktuellen Wert zugewiesen*/
                aktuell->prev = neu;      /* Vor-Zeiger des Aktuellen werts wird auf die neue liste gesetzt*/
                neu = aktuell;            /* Neue Liste bekommt aktuellen wert zugewiesen*/
                neu->prev=neu->prev->prev;
                aktuell->next=aktuell->next->next;
       
                printf("bin im Random-Else\n");
                printf("Neu-else: %s\n ",neu);
                printf("Neu-Prev-else: %s\n ",neu->prev);
                printf("Neu-Next-else: %s\n ",neu->next);
             }
          }
       return neu;
    }


    int main(int argc,char **argv)
    {
       char tastendruck=' ';
       t_liste *start,*aktuell;
       int random=0,repeat=0,i;

       fprintf(stdout,"\n\n\nTracklist-Steuerung V 0.2\n");
       fprintf(stdout,"------------------------------------------------- \n");
     
       for(i=0;i<argc;i++)                     //überprüfen ob repeat oder random gesetzt wurde
       {
          if(strcmp("-random",argv[i])==0)
          {
             random=1;         
             fprintf(stdout,"Player ist im Random-modus!\n");
          }
          if(strcmp("-repeat",argv[i])==0)
          {
             repeat=1;
             fprintf(stdout,"Repeat-modus: Bei vorspulen werden vorangehende Tracks nicht entfernt.\n");
          }
       }


     /* später ...  */
    /*
       if(random=1)
       {
    */      start=dateilesen(argv[argc-1]); /*
       }
       else
       {
          start=rando(argv[argc-1]);
       }
    */
       aktuell=(t_liste*)malloc(sizeof(t_liste));
       aktuell->prev=NULL;
       aktuell->next=start;
       fprintf(stdout,"------------------------------------------------- \n");
       fprintf(stdout,"Abspielen:\t\tSpace \n");
       fprintf(stdout,"Previous Track: \t  < \n");
       fprintf(stdout,"Next Track:\t \t  > \n");
       fprintf(stdout,"Beenden:\t \t  q \n");

       while(1)
       {
          tastendruck=getch();
         
          switch(tastendruck)
          {
          case 'q': killall(aktuell); return EXIT_SUCCESS;
                   
          case '>': if(repeat==1)
                  {
                     aktuell=rft(aktuell); break;
                  }
                  else
                  {
                     aktuell=followtrack(aktuell); break;
                  }

          case '<': aktuell=prevtrack(aktuell); break;
           
          case 'r': aktuell=rando(aktuell); break; 

          case ' ': if(repeat==1)
                {
                   aktuell=rplay(aktuell->next); break;
                }
                else
                {
                   aktuell=play(aktuell->next); break;
                }

          default: fprintf(stdout,"Eingabe nicht korrekt.\n"); break;
          }     
       }
       free(start);
       free(aktuell);
       return EXIT_SUCCESS;
    }



    Re: Mischen von Einträgen einer doppelt verketteten Liste

    Zuul - 23.03.2007, 02:16

    Problem Gelöst !
    Hey meine Lieben !

    Nach zahlreichen wut-AUS und nerven-ZUSAMMEN-brüchen hab ich nun, dank meines bestn freundes, endlich den code fertig ...
    für intressierte hier der complette source

    mfg
    Zuul
    Code: /********************************************************/
    /*                                          */
    /*                  Audioplayer                  */
    /*                                                           */
    /*                                          */
    /********************************************************/   

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <conio.h>
    #include <time.h>

    typedef struct s_liste
    {
       char *titel;
       struct s_liste *next;
       struct s_liste *prev;

    }   t_liste;

    t_liste *dateilesen(char *pfad);                        /* FKT Prototypen */
    t_liste *play(t_liste *track);
    t_liste *rplay(t_liste *track);                                                   
    t_liste *rando(t_liste *track);                     /* später t_liste *rando(char *pfad);   */
    t_liste *prevtrack(t_liste *track);
    t_liste *followtrack(t_liste *track);
    t_liste *rft(t_liste *track);
    t_liste *killall(t_liste *track);
    int myrand(int size);

    int counter=0, random=0;
    t_liste *dateilesen(char *pfad)
    {
       FILE *datei;
       char zwischen[250];
       t_liste  *current,*following, *head;

       datei=fopen(pfad,"r");
       
       current=(t_liste*)malloc(sizeof(t_liste));         /* speicherplatz reservieren */
       head=current;
       current->next=NULL;                           /* nächster zeiger zeigt derzeit auf nichts */
       current->prev=NULL;                           /* zeiger kann noch auf keinen vorhergehenden Track zeigen */
       
       if(datei==NULL)
       {
          printf("Fehler beim lesen der Datei\n");         /*Testen ob datei Geladen wurde   */
         exit(1);
       }
       else
       {
          while(fgets(zwischen,250,datei))
          {
             if(counter==0)
             {
                fgets(zwischen,250,datei);                   /* datei-header übergehen*/
             }
             {
             current->titel=strdup(zwischen);                /* Aktuelle Zeile in Current-Titel kopieren */
             following=(t_liste*)malloc(sizeof(t_liste));    /* für den folgenden titel speicher reservieren */
             following->prev=current ;                       /* den Folgenden zeiger der zürück zeigt auf den momentan Track zeigen lassen */
             current->next=following;                        /* den Zeiger der vor zeigt auf den folgenden Track zeigen lassen */
             current=following;                              /* den momentanen Track durch den Folgenden Ersetzen. */
             following->next=NULL;                           /* der folgezeiger des Nächsten Tracks existiert noch nicht. */
             counter++;         
             }
          }
         fprintf(stdout,"Die Tracklist beinhaltet %d Tracks\n",counter);
       }   
     
       fclose(datei);
       return head;
    }

    t_liste *rplay(t_liste *track)
    {
       if(track==NULL)
       {   
             while(track->prev != NULL)                  /* Wieder zurück zum Anfang "spulen" */
          {
             track = track->prev;
          }
          if(random == 1)                           /* falls im random modus */
          {
             fprintf(stdout,"Playlist zuende. Neue wird gemischt.\n");
             return rando(track);
          }
          else
          {
             fprintf(stdout,"Playlist zuende. Von vorne beginnen (repeat).\n");
             return track;
          }
       }
       else
       {
          printf("Momentaner Track: %s", *track);                  /* Ausgabe des gewählten Titels*/
          return(track);
       }
    }

    t_liste *play(t_liste *track)
    {
       if(track==NULL)
       {
          fprintf(stdout,"Kein weiterer Track.\n");
          return EXIT_SUCCESS;
       }
       else
       {      
          t_liste *help=track->prev;
             
          fprintf(stdout,"Momentaner Track: %s", *track);         /* Ausgabe des gewählten Titels */
          track->prev=NULL;
          free(help);
          return(track);
       }
    }

    t_liste *killall(t_liste *track)                              /* Allocierten Speicherbereich wieder frei geben*/
    {
       t_liste *help=NULL;

       while(track->next!=NULL)
       {
          track=track->next;
       } 
       help=track;
       while(help!=NULL)
       {
          help=track->prev;
          free(track);
          track=help;
       }
       fprintf(stdout,"Das Program wurde beendet.\n");
       return EXIT_SUCCESS;
    }

    t_liste *prevtrack(t_liste *track)
    {
       if(track==NULL||track->prev==NULL)               /* Zeigt der Nächste Track auf NULL ist die Liste durchgearbeitet */
       {
          fprintf(stdout,"Es gibt keinen vorhergehenden Titel. Aktueller wird wiederholt. \n");
          return track;
       }
       else                                   
       {
          track=rplay(track->prev);
          return track;                                 /* Der Nächste Track wird returned */
       }
    }

    t_liste *rft(t_liste *track)                        /* rft gibt folgenden titel aus und lässt tracks in liste */
    {
       if(track->next==NULL)
       {
             while(track->prev != NULL)               /*Playlist zuende - Wieder zurück zum Anfang "spulen" */
          {
             track = track->prev;
          }
          
           if(random == 1)                        /* falls im random modus */
          {
             fprintf(stdout,"Playlist zuende. Neue wird gemischt.\n");
             return rando(track);
          }
          else
          {
             fprintf(stdout,"Playlist zuende. Von vorne beginnen (repeat).\n");
             return track;
          }
       }
       else
       {
          track=rplay(track->next);
          return track;
       }
    }

    t_liste *followtrack(t_liste *track)                 /* followtrack gibt folgenden titel aus & löscht vorhergehenden track */
    {

       if(track->next==NULL)
       {
          fprintf(stdout,"Es gibt keinen folgenden Titel.Programm wird beendet.\n");
          return EXIT_SUCCESS;
       }
       else
       {   
          t_liste *help;
         help=track;
          track=track->next;
          track->prev=NULL;
          free(help);
          rplay(track);
          return track;
       }
    }

    int myrand(int size)
    {
        int rand_seed = time(NULL);
        rand_seed = rand_seed * 1103515245 +12345;
        return (unsigned int)(rand_seed / 65536) % (size+1);
    }

    t_liste *rando(t_liste *track)            /* Idee wäre, rando statt dateilesen aufzurufen also t_liste *rando(char *pfad) */
    {                                 /* damit die liste geshuffled ist und mit andren Funktionen */
                                     /* direkt angesteuert werden kann.*/
       t_liste *aktuell;
       t_liste *altHead;
       t_liste *oldPrev;
       t_liste *oldNext;
       t_liste *neu = (t_liste*)malloc(sizeof(t_liste));
       t_liste *neuHead;
       
       int size = counter;
       int isfirst=1;
        int zahl = myrand(size), i = 1;
       
       altHead = track;                     /* den head der alten liste speichern*/

       while(size > 0)                        /* Solange noch Items in der alten Liste vorhanden sind */
       {      
          zahl = myrand(size);               /* Per Zufall ein Element auswählen */
          aktuell = altHead;                  /* Das gewählt Element selektieren*/
          for(i=1; i < zahl; i++)
          {
             aktuell = aktuell->next;   
          }
          
          /*Das gewählte Element aus der alten Liste herausschneiden und diese wieder richtig verknüpfen*/
          oldPrev = aktuell->prev;
          oldNext = aktuell->next;
          if(!(oldPrev == NULL && oldNext == NULL))
          {
             if(oldPrev == NULL)
             {
                oldNext->prev = NULL;
                /*Da das zu herausschneidende Element der Head war, noch das zweite Element neu als Head setzen*/
                altHead = aktuell->next;
             }
             else
             {
                if(oldNext != NULL)
                {
                   oldNext->prev = oldPrev;
                }
             }
             if(oldNext == NULL)
             {
                oldPrev->next = NULL;
             }
             else
             {
                if(oldPrev != NULL)
                {
                   oldPrev->next = oldNext;
                }
             }
          }
          /* Falls es das erste Element ist, das in die neue Liste kommt, dies anders handhaben */
          if(isfirst)   
          {
             neu = aktuell;
             neu->prev = NULL;
             neu->next = NULL;
             neuHead = neu;
             isfirst=0;   
          }
          else
          {
             neu->next = aktuell;   /* das ausgeschnittene Element wird der nachfolger des letzten der neuen liste */
             aktuell->prev = neu;   /* dementsprechend wird das letzte der neuen liste der vorgänger des neuen elements */
             neu = aktuell;         /* position auf das neue element setzen */
             neu->next = NULL;      /* das neue element hat keinen nachfolger, da letztes der neuen liste!! */
          }      
          size--;
       }/* end While */
       return neuHead;
    }

    int main(int argc,char **argv)
    {
       char tastendruck=' ';
       t_liste *start,*aktuell;
       int repeat=0,i;
       if(argc==1)
       {
          fprintf(stdout,"Datei wie folgt starten: programmname [-repeat][-random] dateiname.txt\n");
          return EXIT_FAILURE;
       }
       fprintf(stdout,"\n\n\nTracklist-Steuerung V 0.2\n");
       fprintf(stdout,"------------------------------------------------- \n");
     
       for(i=0;i<argc;i++)                             /*überprüfen ob repeat oder random gesetzt wurde*/
       {
          if(strcmp("-random",argv[i])==0)
          {
             random=1;         
             fprintf(stdout,"Player ist im Random-modus!\n");
          }
          if(strcmp("-repeat",argv[i])==0)
          {
             repeat=1;
             fprintf(stdout,"Repeat-modus: Bei vorspulen werden vorangehende Tracks nicht entfernt.\n");
          }
       }
       start = dateilesen(argv[argc-1]);
       
       /* testen ob random aktiviert */
       if(random==1)   
       {
          start = rando(start);   
       }
       
       aktuell=(t_liste*)malloc(sizeof(t_liste));
       aktuell->prev=NULL;
       aktuell->next=start;
       fprintf(stdout,"------------------------------------------------- \n");
       fprintf(stdout,"Abspielen:\t\tSpace \n");
       fprintf(stdout,"Previous Track: \t  < \n");
       fprintf(stdout,"Next Track:\t \t  > \n");
       fprintf(stdout,"Beenden:\t \t  q \n");

       while(1)
       {
          tastendruck=getch();                     /* Einlesen mit getch damit nicht mit Enter bestätigt werden muss */
         
          switch(tastendruck)
          {
          case 'q': killall(aktuell); return EXIT_SUCCESS;
                   
          case '>': if(repeat==1)
                  {
                     aktuell=rft(aktuell); break;
                  }
                  else
                  {
                     aktuell=followtrack(aktuell); break;
                  }

          case '<': aktuell=prevtrack(aktuell); break;
           
          case ' ': if(repeat==1)
                {
                   aktuell=rplay(aktuell->next); break;
                }
                else
                {
                   aktuell=play(aktuell->next); break;
                }
          default: fprintf(stdout,"Eingabe nicht korrekt.\n"); break;
          }     
       }
       free(start);                              /* Freigeben von benötigtem Speicher */
       free(aktuell);
       return EXIT_SUCCESS;
    }



    Mit folgendem Code, können Sie den Beitrag ganz bequem auf ihrer Homepage verlinken



    Weitere Beiträge aus dem Forum Tutorials.at

    Tutorias für Grafiken in C - gepostet von mitti am Donnerstag 26.04.2007
    HTML/ PHP - gepostet von gs93 am Dienstag 17.10.2006
    string abfragen? - gepostet von Godmaster am Dienstag 03.10.2006
    exit in die konsole tippen für exit - gepostet von necator am Montag 16.07.2007
    Problem mit Turo Pascal Programm - gepostet von Dagoth Dut am Donnerstag 31.08.2006
    Lieblings Tools ? - gepostet von exbs am Dienstag 27.02.2007
    Frauen? - gepostet von Dubbel am Montag 08.01.2007
    mit den 3 Ordnern - gepostet von KevIn am Sonntag 09.07.2006



    Ähnliche Beiträge wie "Mischen von Einträgen einer doppelt verketteten Liste"

    eigentlich lächerlich für schwarze liste-level1 - Ryak (Freitag 24.08.2007)
    Schwarze Liste - Anonymous (Sonntag 11.09.2005)
    Liste der freien Charas - cassy1610 (Sonntag 30.04.2006)
    Aion : The Tower of Eternity - Torque (Montag 15.06.2009)
    Liste - Netherwind-Verteilung - Volupta (Freitag 07.07.2006)
    Rote Liste Zusammensetzung - Friesin (Dienstag 21.08.2007)
    Liste der Serien - Ray (Mittwoch 20.09.2006)
    Schwache Heizung - Mercury (Sonntag 29.01.2012)
    icq liste - bomberpilot (Montag 14.08.2006)
    Gilden Crafter Liste - Woozy (Dienstag 13.11.2007)