chuongpham
chuongpham

Reputation: 66

Insertion sort array of structure by 2 fields

I am making an uno card game with structure of card with fields:

struct card
{
    int rank 
    char *color  
    char *action. 
}

I am able to make it sort by color with insertion. I wonder how could I first sort the array of uno card by color, then sort the rank of each color.

Upvotes: 1

Views: 1465

Answers (3)

chuongpham
chuongpham

Reputation: 66

Thanks to Bo Persoson, this is the solution to my question

void sort(card *a, int length) {
int j;
for (int i = 1; i < length; i++) {
    j = i;
    while (j > 0 && a[j].color < a[j - 1].color || (a[j].color == a[j - 1].color && a[j].rank < a[j - 1].rank)) {
        swap(&a[j], &a[j - 1]);
        j--;
    }
}

}

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311048

Let's assume that the structure is called card and c1 and c2 are two pointers to objects of the structure.

In this case you should use the following condition to compare elements of the array

int comparison( card *c1, card *c2 )
{
    int color_cmp = strcmp( c1->color, c2->color ); 
    return color_cmp < 0 || ( color_cmp == 0 && c1->rank < c2->rank );
}

This predicate is considered as a boolean predicate. If you need a comparison function thet will be used in the standard algorithm qsort then you have to change it such a way that it returns -1, 0 or 1.

For example

int comparison( const void *p1, const void *p2 )
{
    const card *c1 = ( const card * )p1;
    const card *c2 = ( const card * )p2;

    int color_cmp = strcmp( c1->color, c2->color ); 

    if ( color_cmp < 0 )
    {
        return -1;
    }
    else if ( color_cmp > 1 )
    {
        return 1;
    }
    else
    { 
        return ( c2->rank < c1->rank ) - ( c1->rank < c2->rank );
    }
}

Upvotes: 0

Zachi Shtain
Zachi Shtain

Reputation: 836

Assuming you are overloading the operator <, you should implement a condition that compares the color of the cards and their rank. Since you want that the primary sorting criteria will be the color you should check that one first. I would implement it something like this:

int colorCompareResult = strcmp(card1.color, card2.color);
if (colorCompareResult < 0)
    return true;
else if (colorCompareResult == 0 && card1.rank < card2.rank)
    return true;
else
    return false;

Upvotes: 0

Related Questions