Tri d’un tableau à l’aide de plusieurs critères de sorting (QuickSort)

J’essaie de savoir comment (à l’aide d’un algorithme quicksort) sortinger un tableau de struct par 2 critères Par exemple, disons que j’ai une structure de:

struct employee{ char gender[12]; char name[12]; int id; }; 

Dites que mon entrée est:

 struct employee arr[3]= { {"male","Matt",1234}, {"female","Jessica",2345}, {"male","Josh",1235} }; 

Je souhaite sortinger les éléments en fonction du sexe, puis des identifiants par ordre croissant. Un exemple serait que tous les mâles soient imprimés en premier avec leurs identifiants dans l’ordre, puis que toutes les femelles portent les leurs. J’essaie de faire cela sans utiliser la fonction qsort mais je n’ai pas la moindre idée de comment vérifier. Voici ma fonction de sorting:

 void quicksort(struct employee *arr, int left, int right) { int pivot, l, r, temp; if(left < right) { p = left; l = left; r = right; while(l < r) { while(arr[l].id <= arr[p].id && l  arr[p].id && r >= left) r--; if(l < r) { temp = arr[l].id; arr[l].id = arr[r].id; arr[r].id = temp; } } temp = arr[r].id; arr[r].id = arr[p].id; arr[p].id = temp; quicksort(arr, left, r-1); quicksort(arr, r+1, right); } } 

Aucune suggestion? Je pensais pouvoir utiliser strcmp mais je ne peux pas trouver où l’inclure dans la fonction.

Vous pouvez certainement intégrer la fonction de comparaison et un swapper à cet égard. Ce code ci-dessous est assez basique et repose sur des pointeurs valides, mais vous aurez l’idée. J’ai également pris la liberté de réduire votre sorting rapide, de réparer ce qui se passait en cours de route (j’espère).

 #include  #include  #include  // employee record struct employee { char gender[12]; char name[12]; int id; }; // swap employee records void swap_employee(struct employee *left, struct employee *right) { struct employee tmp = *right; *right = *left; *left = tmp; } // compare employee records int compare_employee(const struct employee* left, const struct employee* right) { int gender = strcmp(left->gender, right->gender); return (gender ? gender : (left->id - right->id)); } // quicksort for employees static void quicksort_(struct employee *arr, int left, int right) { struct employee p = arr[(left+right)/2]; // as good as any int l = left, r = right; // movable indicies while (l <= r) { while (compare_employee(arr+l, &p) < 0) ++l; while (compare_employee(arr+r, &p) > 0) --r; if (l <= r) { swap_employee(arr+l, arr+r); ++l; --r; } } if (left < r) quicksort_(arr, left, r); if (l < right) quicksort_(arr, l, right); } // exposed API void quicksort(struct employee *arr, int count) { if (arr && (count>0)) quicksort_(arr, 0, count-1); } /* sample usage */ int main(int argc, char *argv[]) { struct employee arr[]= { {"male","Matt",1234}, {"female","Jessica",2345}, {"male","Josh",1235}, {"female","Betsy",2344}, {"male","Roger",1233} }; quicksort(arr, sizeof(arr)/sizeof(arr[0])); for (int i=0;i 

Résultats

 female, Betsy, 2344 female, Jessica, 2345 male, Roger, 1233 male, Matt, 1234 male, Josh, 1235 

C’est pas difficile. Vous avez juste besoin d’une fonction (ou d’un bloc de code voyant que vous le voulez “codé en dur”) pour comparer vos structures. Dans l’exemple de code que vous avez donné, vous comparez l’object actuel à l’aide de arr[l].id <= arr[p].id . C’est-à-dire que vous envisagez de vous identifier pour déterminer l’emplacement de votre élément. Vous avez juste besoin de comparer en utilisant les autres champs à ce stade. Ce serait beaucoup plus ordonné avec une fonction (je vous en ai donné une dans votre question précédente).

De plus, vous ne faites que déplacer les champs d'identifiant lorsque vous échangez, laissant ainsi le nom et le sexe inchangés dans vos éléments de données. Vous devriez déplacer toute la structure.

Utilisez simplement le qsort intégré et transmettez-lui une fonction de comparaison qui compare d’abord le genre et ne consulte le numéro d’ID que dans le cas de “liens” dans la première comparaison.

Je pense que vous devriez d’abord sortinger votre tableau par sexe, un pour les hommes et un pour les femmes. Utilisez ensuite la fonction sorting rapide pour sortinger ces deux tableaux.

Vous pouvez utiliser strcmp pour sortinger le tableau d’origine en deux tableaux: un pour les hommes et un pour les femmes.

 int compare_employee (struct employee * a, struct employee * b) { int diff = strcmp(a->gender, b->gender); if (diff) // if gender different return -diff; // sort descending, please double check this and reverse in case I am wrong return a->id - b->id; // else sort by id } 

Emettra un nombre négatif si a < b , positif si a > b , zéro si elles sont égales.

Utilisez-le vous-même dans votre propre sorting rapide ou comme comparateur de qsort .