简体   繁体   中英

How to sort data in a struct array using qsort (C)

I have a struct array (each element is a row) that has a float (each element is a column). How would I sort this by column assuming that the table has been fully initalized.. how would I go about sorting by floats using qsort(). I am completely stuck. My code:

typedef struct row
{   
    float value[20];
}ROW;

//in the main function I initalize ROW table[100]

my qsort call: 
qsort(table, row, sizeof(*table), &compare);


my compare function:

int compare(const void* first, const void *second)
{
    float firstTotal = (*(ROW **)first)->value;
    float secondTotal = (*(ROW **)second)->value;

    return firstTotal - secondTotal;
}

If you want to sort elements within each struct, then your qsort call will operate on the array of floats.

qsort(((ROW*)->value), 20, sizeof(float), comparefloats);

Then the comparison is just between two floats.

int comparefloats(const void *left, const void *right) {
    float lt = *(float *)left;
    float rt = *(float *)right;
    return (fabs(lt - rt) < 0.0001)? 0:
                              lt - rt > 0? 1: -1;
}

Sorting the rows themselves, if there's a larger array of them, will involve a less-straightforward notion of comparing two arrays.

As you say, you want to sort "by columns", in that case, unfortunately qsort is not your friend. It's not a stable sort, you see. So you can't just sort row by row in increasing order of priority.

To sort columns, one at a time (or sequentially, if you find a stable-sort with the same interface), you'll need a different comparison function for each column, or a comparison with different behavior each time it's called. The obvious way would be with a global variable.

int column_to_compare;
int comparefloatcolumn(const void *left, const void *right) {
    float lt = (*(ROW *)left).value[ column_to_compare ];
    float rt = (*(ROW *)right).value[ column_to_compare ];
    return (fabs(lt - rt) < 0.0001)? 0:
                              lt - rt > 0? 1: -1;
}

Then you need to set the column before each call to qsort.

column_to_compare = 0;
qsort(rowarray, 100, sizeof(ROW), comparefloatcolumn);

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