Home > Net >  Sort struct array in lexicographical order
Sort struct array in lexicographical order

Time:03-22

I need to sort students according to their surname or if their surname is the same according to their name in lexicographical order.

#include <stdio.h>
struct Student {
  char name[20], surname[20];
};
void sort(struct Student students[], int n) {
  int i, j, temp;
  for (i = 0; i < n; i  )
    for (j = i   1; j < n; j  )
      if (students[j].surname > students[i].surname ||
          students[j].name > students[i].name) {
        temp = i;
        students[i] = students[j];
        students[j] = students[temp];
      }
}
void main() {
  struct Student students[6] = {
      {"Mujo", "Mujic"}, 
      {"Meho", "Mujic"}, 
      {"Pero", "Peric"},
      {"Beba", "Bebic"}, 
      {"Mujo", "Mujic"}, 
      {"Fata", "Fatic"},
  };
  sort(students, 6);
  int i;
  for (i = 0; i < 6; i  )
    printf("%s %s\n", students[i].surname, students[i].name);
}

This prints only one student six times. Could you help me to fix this?

  • Note: using auxiliary arrays is not allowed

CodePudding user response:

Your swap code is dubious — broken, I believe. A big warning bell is the type of temp — it needs to be a struct Student.

You have:

    temp = i;
    students[i] = students[j];
    students[j] = students[temp];

You need:

    struct Student temp = students[i];
    students[i] = students[j];
    students[j] = temp;

Obviously, remove the definition int temp; as well.


However, there are other problems too (as ever). You can't usefully compare strings using relational operators — use strcmp(). And your ordering test is wrong too, even when revised to use strcmp().

This code does the job, sorting names in descending order:

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

struct Student
{
    char name[20];
    char surname[20];
};

static void sort(struct Student students[], int n)
{
    for (int i = 0; i < n; i  )
    {
        for (int j = i   1; j < n; j  )
        {
            int rc = strcmp(students[j].surname, students[i].surname);
            if (rc > 0 ||
                (rc == 0 && strcmp(students[j].name, students[i].name) > 0))
            {
                struct Student temp = students[i];
                students[i] = students[j];
                students[j] = temp;
            }
        }
    }
}

static void dump_array(const char *tag, size_t size, const struct Student *students)
{
    printf("%s (%zu):\n", tag, size);
    for (size_t i = 0; i < size; i  )
        printf("%s %s\n", students[i].surname, students[i].name);
}

int main(void)
{
    struct Student students[] =
    {
        {"Mujo", "Mujic"},
        {"Meho", "Mujic"},
        {"Pero", "Peric"},
        {"Zebra", "Elephant"},
        {"Beba", "Bebic"},
        {"Mujo", "Mujic"},
        {"Abelone", "Shells"},
        {"Fata", "Fatic"},
    };
    enum { NUM_STUDENTS = sizeof(students) / sizeof(students[0]) };

    dump_array("Before", NUM_STUDENTS, students);
    sort(students, NUM_STUDENTS);
    dump_array("After", NUM_STUDENTS, students);

    return 0;
}

Output:

Before (8):
Mujic Mujo
Mujic Meho
Peric Pero
Elephant Zebra
Bebic Beba
Mujic Mujo
Shells Abelone
Fatic Fata
After (8):
Shells Abelone
Peric Pero
Mujic Mujo
Mujic Mujo
Mujic Meho
Fatic Fata
Elephant Zebra
Bebic Beba
  • Related