0

I need a code that sorts an array of structs in ascending order by name or age using the bubblesort algorithm.

I read all the elements and I understand the part of sorting. The problem is that I should only declare one bubblesort algorithm to be able to sort according to name or age. Also when two names or ages are the same then I should compare the elements that are not the same. For this I should use a function pointer. I have just starting using function pointers and I can't see a way out here. A little help would be much appreciated.

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

struct person {
    char name [30];
    int age;
};

void bubblesort(struct person *prs, int n)
{
struct person temp;
int i, j , a,b;


for(i=0;i<n; i++)
{
    for(j=0; j <n-1; j++)
    {
        a=strcmp(prs[j].name, prs[j+1].name);
        b=prs[j+1].age - prs[j].age;

        if(a>0)
        {
            temp=prs[j];
            prs[j]=prs[j+1];
            prs[j+1]=temp;
        }
        else if(a==0 && b<0)
        {
            temp=prs[j];
            prs[j]=prs[j+1];
            prs[j+1]=temp;
        }
    }
}
}

int main()
{

int n, i;
 struct person *prs;

scanf("%d", &n);
getchar();

prs=(struct person *)malloc(sizeof(struct person)*n);

for(i=0;i<n;i++)
{
    fgets(prs[i].name, 30, stdin);
    prs[i].name[strlen(prs[i].name)-1]='\0';
    scanf("%d", &prs[i].age);
    getchar();
}

bubblesort(prs,n);

 for(i=0;i<n;i++)
 {
   printf("{%s, %d};", prs[i].name, prs[i].age);

 }
 return 0;
 }
3
  • 3
    Look at the prototype of qsort. It shuold provide you with enough hints about how to write your sorting function to be general. Commented Feb 19, 2017 at 10:19
  • I can't use qsort. I already know how to use qsort. Instead of qsort I had to create this bubblesort function. Commented Feb 19, 2017 at 11:30
  • 2
    I didn't say you use qsort. I said you study how it's defined so you can write your own sorting function, jeez... Commented Feb 19, 2017 at 11:32

3 Answers 3

1

You can use an approach similar to the approach used by the standard C function qsort.

Add a third parameter to the function bubble_sort. For example

void bubble_sort( struct person *p,
                  int n, 
                  int comp( const struct person *p1, const struct person *p2 ) );

Though it would be much better to declare the second parameter of the function as having type size_t

void bubble_sort( struct person *p,
                  size_t n, 
                  int comp( const struct person *p1, const struct person *p2 ) );

Then define two functions that compare objects of the type struct person. Each function has to return a negative value if the first item is less than the second item, positive value if the first item is greater than the second item and zero otherwise.

The functions can look like

int comp_by_name( const struct person *p1, const struct person *p2 )
{
    int str_cmp = strcmp( p1->name, p2->name );
    int int_cmp = ( p2->age < p1->age ) - ( p1->age < p2->age );

    return str_cmp != 0 ? str_cmp : int_cmp;
}

int comp_by_age( const struct person *p1, const struct person *p2 )
{
    int str_cmp = strcmp( p1->name, p2->name );
    int int_cmp = ( p2->age < p1->age ) - ( p1->age < p2->age );

    return int_cmp != 0 ? int_cmp : str_cmp;
}

And inside the bubble_sort write the following if statement

if ( comp( &prs[j+1], &prs[j] ) < 0 )
{
    struct person tmp = prs[j+1];
    prs[j+1] = prs[j];
    prs[j] = tmp;
}

And at last call the function bubble_sort either like

bubble_sort( prs, n, comp_by_name );

if you want to sort the array by names or

bubble_sort( prs, n, comp_by_age );

if you want to sort the array by ages.

Sign up to request clarification or add additional context in comments.

Comments

0

Use this function prototype for bubblesort:

void bubblesort(struct person *prs, int n, int (*cmp)(struct person *a, struct person *b)) {...}

Now create a comparison function to compare two persons:

int cmpTwoPersons(struct person *a, struct person *b) {...}

This function should return a number larger than 0 if a>b, smaller than 0 if a

Call your bubblesort using this comparison function:

bubblesort(prs, n, cmpTwoPersons);

Now you use cmp inside your bubblesort:

void bubblesort(...) {
    ...
    int cmpResult = cmp(prs[j], prs[j+1]);
    if (cmpResult > 0) {
        // j is large than j+1
    } else {
        // j is smaller than or equal to j+1
    }
    ...
}

1 Comment

Thank you very much! I found your answer very helpful and I understood it all. The problem now stands that I should call the other function when the compare function returns 0. Should I declare and array of pointer functions and after that compare cmp with the elements and pick the element that i not the same?
0

Your bubble sort signature can be:

void bubblesort(void **prs, int n, int (*cmp)(void *p1, void *p2))

You now compare in bubble sort as:

    int cmpResult = cmp(prs[j], prs[j+1]);

The compare routine's signature is:

int cmpTwoPersons(struct person *a, struct person *b);

and call bubble sort as:

bubblesort(prs, n, cmpTwoPersons);

By using void * as data type, you make the bubble sort algorithm indpendent of the data to be sorted and the compare function says how to compare two elements. However, the data to be sorted must be an array of pointers so the bubble only needs to swap pointers and not whole structures as it doesn't know their size.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.