Сортировать массив структур в алфавитном порядке, используя сортировку слиянием - PullRequest
1 голос
/ 30 марта 2020

Итак, в основном я создал 2 структуры: одну с именем product, а другую с именем order. В заказе есть массив товаров, и у каждого товара есть описание, представляющее собой строку.

Я пытаюсь отсортировать массив товаров в порядке, названном set_prod, в алфавитном порядке, мне нужно отсортировать его на основе описания продуктов.

Для этого я нашел алгоритм сортировки слиянием, который сделал это, но когда я пытаюсь адаптировать его для сортировки своих структур, он выдает ошибку ошибки сегментации (дамп памяти) и другие ошибки, которые я не понимаю также.

Вот код:

typedef struct product {
   int ident;
   char desc[MAX_CHARS]; /* string that describes a product eg. "bread" */
   int price;  /* price of the product*/
   int weight; /* weight of the product eg. 2kg */
   int quant; /* quantity of the product in stock */
   int state_prod;
} product;

typedef struct order {
   int ident_o;
   product set_prod[MAX_PRODS_OD]; /* Set of products */
   int state;
} order;

void Merge_str_2(product *arr[], int low, int mid, int high) //Merging the Array Function
{
    int nL = mid - low + 1;
    int nR = high - mid;

    char **L = malloc(sizeof(char *) * nL);
    char **R = malloc(sizeof(char *) * nR);
    int i;
    for (i = 0; i < nL; i++) {
        L[i] = malloc(sizeof(arr[low + i]->desc));
        strcpy(L[i], arr[low + i]->desc);
    }
    for (i = 0; i < nR; i++) {
        R[i] = malloc(sizeof(arr[mid + i + 1]->desc));
        strcpy(R[i], arr[mid + i + 1]->desc);
    }
    int j = 0, k;
    i = 0;
    k = low;
    while (i < nL && j < nR) {
        if (strcmp(L[i], R[j]) < 0)
            strcpy(arr[k++]->desc, L[i++]);
        else
            strcpy(arr[k++]->desc, R[j++]);
    }
    while (i < nL)
        strcpy(arr[k++]->desc, L[i++]);
    while (j < nR)
        strcpy(arr[k++]->desc, R[j++]);
}

void MergeSort_str(product **arr[], int low, int high) //Main MergeSort function
{
    if (low < high) {
        int mid = (low + high) / 2;
        MergeSort_str(arr, low, mid);
        MergeSort_str(arr, mid + 1, high);
        Merge_str_2(arr, low, mid, high);
    }
}

Я могу скомпилировать только с gcc -Wall -Wextra -Werror -ansi -pedantic, и я получаю эти предупреждения:

In function ‘main’:

warning: passing argument 1 of ‘MergeSort_str’ from incompatible pointer type [-Wincompatible-pointer-types]

          MergeSort_str(sistem_orders[ide].set_prod,0,MAX_PRODS_OD-1);
                        ^~~~~~~~~~~~~

note: expected ‘product *** {aka struct product ***}’ but argument is of type ‘product * {aka struct product *}’

 void MergeSort_str(product** arr[],int low,int high);
      ^~~~~~~~~~~~~

In function ‘MergeSort_str’:
warning: passing argument 1 of ‘Merge_str_2’ from incompatible pointer type [-Wincompatible-pointer-types]
         Merge_str_2(arr,low,mid,high);
                     ^~~
note: expected ‘product ** {aka struct product **}’ but argument is of type ‘product *** {aka struct product ***}’

void Merge_str_2(product* arr[],int low,int mid,int high)
      ^~~~~~~~~~~

Серьезно любой Мы будем признательны за помощь, потому что я ничего не понимаю в этих ошибках.

1 Ответ

1 голос
/ 30 марта 2020

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

Возможно, проще всего просто использовать функцию stdlib qsort (которая выполняет быструю сортировку, а не сортировку слиянием), которая имеет API, предназначенный для сортировки массива произвольных объектов:

int product_compare(const void *a_, const void *b_) {
    const product *a = a_;
    const product *b = b_;
    return strcmp(a->desc, b->desc); }

... в основной (или другой функции) :

qsort(sistem_orders[ide].set_prod, MAX_PRODS_OD, sizeof(product), product_compare);

Обратите внимание, что это приведет к сортировке пустых элементов в начале массива, что может быть не тем, что вы хотите - вы, вероятно, хотите игнорировать пустые элементы и сохранять непустые элементы в front, и в этом случае вы действительно хотите расширить struct order с помощью счетчика количества продуктов и передать этот счет в qsort в качестве второго аргумента.

...