использование qsort для сортировки структурных указателей по различным переменным - PullRequest
3 голосов
/ 24 марта 2012

Я пытаюсь понять сортировку библиотеки c в контексте указателей на структуры. Вот существующий код, которым я хотел бы манипулировать:

Состав:

#define MAX_NAME 20
#define NUM_MONTHS 12

typedef struct EMP {
    char name[MAX_NAME+1];
    int monthSales[NUM_MONTHS];
    int total;
} Emp;

Глобальная инициализация данных и их размер:

Emp *data;//where all entries are kept
int empSize;

и я построил 2 массива указателей Emp, которые я хотел бы ссылать на данные в разных порядках:

Emp *nameArray[empSize];//an array of pointers to point to entries alphabetically
Emp *salesArray[empSize]; //an array of pointers to pointing to entries by sales

после того, как они были назначены одинаково, я хотел бы использовать qsort, чтобы расположить их по-разному. nameArray в алфавитном порядке, используя имя в структуре и salesArray от наибольшего к наименьшему, используя сумму в структуре

Как должны выглядеть методы сравнения и аргументы qsort?

Спасибо

Ответы [ 2 ]

3 голосов
/ 24 марта 2012

Вам просто нужно определить две разные функции сравнения.Каждая функция сравнения должна иметь два указателя для аннулирования (в этом случае вы должны привести их к типу Emp **) и затем вернуть отрицательное целое число, ноль или положительное целое число, если первая запись меньше, равна илибольше, чем второе, соответственно.

Для сортировки на основе итогов вы можете просто вычесть вторую total из первой.Если первое итоговое значение меньше второго, это приводит к отрицательному числу, и наоборот, если первое итоговое значение больше второго.Когда они равны, возвращается ноль.

int compareByTotal(const void *first, const void *second)
{
    int firstTotal = (*(Emp **)first)->total;
    int secondTotal = (*(Emp **)second)->total;

    return firstTotal - secondTotal;
}

Второй, поскольку это сравнение строк, может возвращать значение strcmp (которое подчиняется тем же соглашениям о возвращаемых значениях):

int compareByName(const void *first, const void *second)
{
    const char *firstName = (*(Emp **)first)->name;
    const char *secondName = (*(Emp **)second)->name;

    return strcmp(firstName, secondName);
}

Тогда вы можете просто позвонить qsort, передав им имена функций:

/* given: */
Emp *nameArray[empSize];//an array of pointers to point to entries alphabetically
Emp *salesArray[empSize]; //an array of pointers to pointing to entries by sales

/* use: */
qsort(nameArray, empSize, sizeof(*nameArray), &compareByName);
qsort(salesArray, empSize, sizeof(*salesArray), &compareByTotal);
1 голос
/ 24 марта 2012

Пример сортировки по именам:

#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME 20
#define NUM_MONTHS 12

typedef struct EMP {
  char name[MAX_NAME + 1];
  int monthSales[NUM_MONTHS];
  int total;
} Emp;

int compareName(const void * a, const void * b)
{
  return (strcmp(((Emp*)a)->name, ((Emp*)b)->name));
}

int main()
{
  Emp *data;
  int empSize = 100;
  qsort(data, empSize, sizeof(Emp), compareName);
  // qsort(data, empSize, sizeof(Emp), compareSales);
  return 0;
}
...