简体   繁体   中英

Linked list QuickSort C

I wrote some simple code that sorts a list that contains passwords, and frequency of usage of this password. The problem is, after reading the text file, the nodes are not connecting together. I can't understand why. It keeps only the last value.

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


typedef struct list_element{
    char passwort[100];
    int haufigkeit;
    struct list_element *next;
} list_element;

typedef struct list{

    list_element *first;
    list_element *last;
} list;


void init_list(list* mylist)
{
    mylist->first=NULL;
    mylist->last=NULL;
}


// Diese Funktion fügt Listenelemente am Anfang der Liste an
void insert_front(list_element* le, list* mylist)
{
    if(mylist->first == NULL){
        le->next = mylist-> first;
        mylist->first=le;
        mylist->last=le;

        printf("%s %d \n",le->passwort, le->haufigkeit);

    }
    else {
        le->next = mylist-> first;
        mylist->first= le;

    }

    // printf("%s %d \n",le->passwort, &le->haufigkeit);

}

// Speicher für Listenelemente wieder freigeben
void free_list(list* mylist)
{
    free((mylist)->first);
    free(mylist);
    mylist=NULL;
}


// Namen, Zahlen Paare in Liste einlesen
void read_data(char* filename, list* mylist)
{
    assert(mylist != NULL);
    FILE* f=fopen(filename,"rb");
    assert(f != NULL);
    list_element* temp = malloc(sizeof(list_element));// * Speicher allozieren

    while (fscanf(f,"%s %d",temp->passwort, &temp-> haufigkeit) != EOF)
    {

        fscanf(f,"%s %d",temp->passwort, &temp-> haufigkeit);// * Daten in list_element einlesen
        printf("%s %d \n",temp->passwort, temp->haufigkeit);

        insert_front(temp, mylist); // * insert_front benutzen um list_element in Liste einzufügen

    }
    fclose(f);
}

// Pivot finden, das die Liste aufteilt
list_element* partition( list* input, list* left, list* right ){
    list_element* pivot= input->first;
    printf("hi");
    list_element *i;
    for(i=input->first; i != NULL; i=i->next){

        if ((i -> haufigkeit) < (pivot -> haufigkeit)){
            insert_front( i, left);
        }
        else{
            insert_front( i, right);
        }

    }

    return pivot;
}


// Hauptfunktion des quicksort Algorithmus
void qsort_list(list* mylist){
    // HIER Code einfügen
    //  list liste= mylist;
    list right;
    list left;
    init_list(&right);
    init_list(&left);
    list_element* pivot;
    printf("hi11");
    if (mylist->last != mylist->first){
        printf("d1 \n");


        pivot = partition(mylist, &left, &right );
        printf("pivot %s %d \n",pivot->passwort, pivot->haufigkeit);

        qsort_list(&left);
        qsort_list(&right);
        /*
         if(left.first == NULL){
         pivot->next = right.first;
         mylist->first = pivot;
         mylist->last = right.last;
         }
         else if(right.first == NULL){
         left.last-> next = pivot;
         mylist->first = left.first;
         mylist->last = pivot;
         }
         else{
         left.last->next=pivot;
         pivot->next = right.first;
         mylist->first = left.first;
         mylist->last = right.last;
         }

         printf("pivot %s %d \n",pivot->passwort, pivot->haufigkeit);
         }
         /* mylist->first = left-> first;
         mylist->last=right->last;
         pivot->next=right->last;
         left.last->next=pivot;
         pivot->next=right.first;
         */
        if(left.first == NULL) {
            // Special

            left.first = pivot;
            mylist->first = left.first;
        } else {
            // REGULAR
            mylist->first = left.first;
            left.last->next = pivot;
        }
        if(right.first == NULL) {
            // Special
            pivot->next = right.first;
            mylist->last = pivot;
        } else {
            // Regular
            pivot->next = right.first;
            mylist->last = right.last;
        }



    }
}

// Liste ausgeben
void print_list(list* mylist){

    list_element* current = mylist-> first;
    while(current != NULL){
        printf("%s %d \n",current->passwort,current->haufigkeit);
        current=current->next;
    }
}

// Argumente einlesen, Liste kreieren, verarbeiten und ausgeben
int main(int argc, char** args)

{
    if (argc != 2)
    {
        printf("Nutzung: %s <Dateiname>\n",args[0]);
        return 1;
    }
    list mylist;
    init_list(&mylist);
    read_data(args[1],&mylist);
    qsort_list(&mylist);
    printf("Sortierte Liste:\n");
    print_list(&mylist);
    free_list(&mylist);
    return 0;
}

the list txt is in form 'password frequency' like

daniel 27720 
welcome 22204 
adobeadobe 27840 
superman 24499 
7777777 19818 
liverpool 18008 
princess 28132 
1qaz2wsx 22180 

Your problem starts in read_data() : you allocate memofry for only one single list_element ( temp ) and overwrite its content with every record you read from the data file. You need to allocate seperate list_element s for each one.

The problem is that your insert_front will not work when next is not NULL. You end up setting the list to NULL which is what you are seeing. You also have no way of knowing what is pointing to that element. Your list struct should contain a prev point as well as a next pointer.

typedef struct list_element{
char passwort[100];
int haufigkeit;
struct list_element *prev;
struct list_element *next;
} list_element;

Here is an update version of your program insert_front method:

void insert_front(list_element* le, list* mylist)
{
  if(mylist->first == NULL){
      mylist->first=le;
      mylist->last=le;
      le->prev = NULL;
      printf("%s %d \n",le->passwort, le->haufigkeit);

  }
  else {
      if (le->prev != NULL) {
        le->prev->next = le->next;
      }        
      le->next = mylist-> first;
      mylist->prev = le
      mylist->first= le;

  }

 // printf("%s %d \n",le->passwort, &le->haufigkeit);

}

This should solve the issue that you are seeing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM