Search code examples
ccomputer-science

Sorting Structures using qsort


I have to use quicksort to sort the states by percentage of population whose ages are equal or greater than 65 years old. I can't figure out on how to use it in the function.

I cannot seem to change the compare function. I also have to make a new file to called output file. I used selection sort to sort the file.

struct state {
    char state_name[150];
    int population_2020;
    int population_2010;
    double ages_under_5;
    double ages_under_18;
    double ages_65_or_greater;
};

void sort_states(struct state list[], int n) 
{
    int i, j, p;
    struct state temp;

    for (i = 0; i < n; i++) {
        p = i;
        for (j = i + 1; j < n; j++) {
            if (list[p].ages_65_or_greater < list[j].ages_65_or_greater) {
                p = j;
            }
        }
        temp = list[p];
        list[p] = list[i];
        list[i] = temp;
    }
}

int main()
{
    char input_file_open[100]; /* initializing the variables */
    char output_file_name[110];

    printf("Enter the file name: \n");
    scanf("%s", input_file_open);

    FILE *input_file = fopen(input_file_open, "r"); 
    FILE *output_file;

    struct state list[100];
    int i, n = 0;

    do {
        fscanf(input_file, "%[^,], %d, %d, %lf, %lf, %lf\n",
               list[n].state_name, &list[n].population_2020,
               &list[n].population_2010, &list[n].ages_under_5,
               &list[n].ages_under_18, &list[n].ages_65_or_greater);
        n++;
    } while (!feof(input_file));

    fclose(input_file);

    for (i = 0; i < n; i++) {
        qsort(input_file, n, sizeof(int), sort_states);
    }

    return 0;
}

Solution

  • You have to define a comparison function for your struct:

    int state_compare_by_age_65_or_gt(const void *s1, const void *s2)
    {
        const struct state *ss1 = s1;
        const struct state *ss2 = s2;
        
        if (ss1->ages_65_or_greater < ss2->ages_65_or_greater)
            return -1;
        else if (ss1->ages_65_or_greater > ss2->ages_65_or_greater)
            return 1;
        else
            return 0;
    }
    

    And a function to print your states (for testing purposes, but you can use it for non-testing purposes as well):

    void state_print(const struct state *st)
    {
        printf("%s\t%d\t%d\t%.2lf\t%.2lf\t%.2lf",
            st->state_name,
            st->population_2020,
            st->population_2010,
            st->ages_under_5,
            st->ages_under_18,
            st->ages_65_or_greater
        );
    }
    

    Now you can use it with qsort():

    int main(void)
    {
        struct state states[] = {
            {"state1", 100, 200, 2.0, 3.0, 13.0},
            {"state2", 100, 200, 2.0, 4.0, 10.0},
            {"state3", 100, 200, 2.0, 5.0, 12.0},
            {"state4", 100, 200, 2.0, 6.0, 11.0},
            {"state5", 100, 200, 2.0, 7.0, 36.0},
            {"state6", 100, 200, 10.0, 8.0, 140.0},
        };
    
        qsort(states, 6, sizeof(struct state), state_compare_by_age_65_or_gt);
    
        for (int i = 0; i < 6; i++) {
            state_print(&states[i]);
            puts("");
        }
    }
    

    Output:

    state2  100 200 2.00    4.00    10.00
    state4  100 200 2.00    6.00    11.00
    state3  100 200 2.00    5.00    12.00
    state1  100 200 2.00    3.00    13.00
    state5  100 200 2.00    7.00    36.00
    state6  100 200 10.00   8.00    140.00