使用多个排序条件对数组进行排序(QuickSort)

我试图找出(使用快速排序算法)如何通过2个标准对结构数组进行排序。 比如说我有一个结构:

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

说我的输入是:

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

我想先按性别对元素进行排序,然后按升序对ID进行排序。 一个例子是,所有的男性首先打印出他们的ID,然后是所有的女性。 我试图这样做而不使用qsort函数,但我没有丝毫想法如何检查。 这是我的排序function:

 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); } } 

有什么建议? 我以为我可以使用strcmp,但我无法弄清楚在函数中包含它的位置。

你当然可以内联比较函数,以及一个交换器。 下面的代码是非常基本的,依赖于有效的指针,但你会明白这个想法。 我也冒昧地削减你的快速排序,修复一路上的事情(我希望)。

 #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 

结果

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

这并不难。 你只需要一个函数(或代码块,看你想要它“硬编码”)来比较你的结构。 在您给出的示例代码中,您使用arr[l].id <= arr[p].id比较当前对象。 那就是你只考虑id来找出你的元素适合的位置。 此时您只需要使用其他字段进行比较。 一个函数会更加整洁(我在你之前的问题中给了你这样一个函数)。

您也只是在交换时移动id字段 - 在数据项中保持名称和性别不变。 你应该移动整个结构。

只需使用内置的qsort ,并传递比较器函数,首先比较性别,并在第一次比较中仅在“tie”的情况下查询ID号。

我认为你应该按性别排序你的arrays,一个是男性,一个是女性。 然后使用quicksort函数在这两个数组中进行排序。

您可以使用strcmp将原始数组排序为两个数组:一个用于男性,一个用于女性。

 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 } 

如果a < b ,则输出负数;如果a > b ,则输出正数;如果相等则输出零。

在您自己的快速排序中使用它或作为qsort比较器使用它。