简体   繁体   中英

sorting linked lists with bubble sort

Why doesn't this bubble sort implementation of sorting linked lists work?

It doesn't sort at all.The main problem area of the code is int the sort function. I have verified that the main works well and the last pointer(next) of the linked list is set to null before calling the sort function. The chain that links the lists should be linked within the if statement that is within the string comparison block and it should return the first link on the list, which would be called by the while statement to access all the members that would have been sorted out, but , it doesn't seem to be working.

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define NAME_SIZE 20

typedef struct record rec;
struct record
{
    char name[NAME_SIZE];
    int age;
    rec* next;
};

void getname(char* name);
rec* sort(rec**First,int i);/*we need to change the addresses they refer to */

int main(void)
{
    rec* Current = NULL;
    rec* Previous = NULL;
    rec* First = NULL;
    char check = '\0';
    int i = 0;

    for(; ;)
    {
        fflush(stdin);
        printf("\nDo you want to enter a%s record?(y/n): ", (check=='\0')?"":"nother");
        scanf("%c", &check);
        if(check == 'n')
            break;

        Current = (rec*)malloc(sizeof(rec));
        if(First == NULL)
        {
            First = Current;
        }
        if(Previous != NULL)
        {
            Previous->next = Current;
        }
        printf("\n");
        printf("\nPlease enter your name: ");
        getname(Current->name);
        printf("\nPlease enter your age: ");
        scanf("%d", &Current->age);
        Previous = Current;
        Current->next = NULL;
        i++;
    }

    Current = sort(&First, i);


    while(Current != NULL)
    {
        printf("\n%s is %d years old ", Current->name, Current->age);
        Current = Current->next;
    }

    return 0;
}

void getname(char *name)
{
    fflush(stdin);
    fgets(name, NAME_SIZE, stdin);
    int length = strlen(name);
    if(name[length - 1] == '\n')
        name[length -1 ] = '\0';
    return;
}


rec* sort(rec** first, int numbers)
{
    rec* pTemp1 = NULL;
    rec* pTemp2 = NULL;
    rec* Temp_first = *first;

    for(int j = 0; j < numbers; j++)
    {
        pTemp1 = *first;
        if(((*first) = (*first)->next)==NULL)
        {/*if end is reached, then break;*/
            break;
        }

        if(strcmp((*first)->name, ((*first)->next->name)) > 0)
        {


            if(((*first)->next) != NULL)
            {
                printf("\n***XXX***Entered***XXX");
                pTemp2 = (*first)->next;
                (*first)->next = pTemp1;
                pTemp1->next = pTemp2;
            }
        }

    }

    return Temp_first;

}

(Omitted freeing up memory for concise). Input

atest  
aatest  
btest  
abtest

and the output isn't sorted:

atest  
aatest  
abtest  

I think you're doing it wrong in the bubble sort function, You seem to be doing repeating the adjacent comparison of the list N times, which is okay but you're only doing comparison for the first two elements of the list. Recall that bubble sort is an O(N^2) algorithm. You need to put that adjacent elements checking into another loop.

Moreover, you can optimize it a bit by changing the outer loop to be dependent on a bubble sort variant which continues the passes till there are no inversions in the list anymore. I changed your bubble sort method according to my style and i was able to see the desired output:

rec* sort(rec** first, int numbers)
{
    int bSwap = 0;
    if(*first == NULL || (*first)->next == NULL)
      return;

    // outer loop for iterating till list is sorted
    while(!bSwap) {
      // iterating over the list comparing and
      // swapping adjacent elements
      rec *curNode = *first;
      rec *prev = *first;
      rec *fwd = (*first)->next;
      bSwap = 1;

      while(fwd) {
        int cmp = strcmp(curNode->name, fwd->name);

        if(cmp > 0) { // inversion found, swap and proceed forward
          if(curNode == *first)
            *first = fwd;
          else
            prev->next = fwd;

          curNode->next = fwd->next;
          fwd->next = curNode;
          prev = fwd;
          fwd = curNode->next;
          bSwap = 0;
        }
        else { // proceed forward
          curNode = prev->next;
          prev = fwd;
          fwd = fwd->next;
        }
      }

    }
    return *first;
}

Here's what i get when i run it:

~/Documents/src : $ ./a.out 

Do you want to enter a record?(y/n): y


Please enter your name: Rohan

Please enter your age: 22

Do you want to enter another record?(y/n): y


Please enter your name: Hema

Please enter your age: 20

Do you want to enter another record?(y/n): y


Please enter your name: Asanala

Please enter your age: 31

Do you want to enter another record?(y/n): n

Asanala is 31 years old 
Hema is 20 years old 
Rohan is 22 years old 

I hope this helps.

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