C中按第二个字段对结构数组排序
我的教授建议我们使用C中按第二个字段对结构数组排序,c,qsort,C,Qsort,我的教授建议我们使用qsort()对结构数组进行排序。然而,我必须来发现它并不稳定。我知道还有其他关于这个话题的帖子,但似乎没有一篇能轻易地稳定我的分类。是否有一种方法可以将qsort()用于第二个数据字段 这是我的密码: #include <stdlib.h> #include <stdio.h> struct Map * collect_values(int n, int *arr); void sort_values(struct Map *ptr, int n)
qsort()
对结构数组进行排序。然而,我必须来发现它并不稳定。我知道还有其他关于这个话题的帖子,但似乎没有一篇能轻易地稳定我的分类。是否有一种方法可以将qsort()
用于第二个数据字段
这是我的密码:
#include <stdlib.h>
#include <stdio.h>
struct Map * collect_values(int n, int *arr);
void sort_values(struct Map *ptr, int n);
void print(struct Map *print_struct, int n);
struct Map{
int value, position;
};
int compare(const void *aptr, const void *bptr){
int a = ((struct Map*)aptr)->value, b = ((struct
Map*)bptr)->value;
return (a > b) - (a < b);
}
int main(){
int size, i;
scanf("%d", &size);
int *arr = (int*) malloc(size*sizeof(int));
struct Map *p = collect_values(size,arr);
qsort(p,size,sizeof(struct Map),compare);
print(p,size);
free(p);
free(arr);
return 0;
}
struct Map * collect_values(int n, int *arr){
int i, position = 0;
struct Map *array = calloc(n,sizeof(*array));
for(i = 0; i < n; i++){
scanf("%d",&arr[i]);
array[i].value = arr[i];
array[i].position = position;
position++;
}
return array;
}
void print(struct Map * print_struct, int n){
int i;
for (i = 0; i < n; i++){
printf("%d : %d\n", print_struct[i].value,
print_struct[i].position);
}
}
我如何维护副本的顺序?我花了很多时间试图弄清楚qsort()
,所以如果可能的话,我想保留它
编辑我不清楚要获取的输出。排序之前,结构数组包含一个值和该值的索引。因此,原始结构数组如下所示:
25 : 0
4 : 1
3 : 2
-3 : 3
5 : 4
5 : 5
7 : 6
88 : 7
4 : 8
1 : 9
int compare(const void *ptr1, const void *ptr2)
{
const struct Map *aptr = ptr1;
const struct Map *bptr = ptr2;
if (aptr->value == bptr->value)
return (aptr->position > bptr->position) - (aptr->position < bptr->position);
else
return (aptr->value > bptr->value) - (aptr->value < bptr->value);
}
排序后,我的代码打印了上面的内容。然而,我所希望的是:
-3 : 3
1 : 9
3 : 2
4 : 1
4 : 8
5 : 4
5 : 5
7 : 6
25 : 0
88 : 7
其中,如果第一个字段中的值相等,则需要按照第二个字段中的值对它们进行排序,因为它们是索引,所以永远不会相等。由于结构有一个表示初始数组顺序的
位置
成员,因此可以轻松模拟稳定排序。在比较函数中,如果两个值
成员相等,则返回基于位置
成员的排序,如下所示:
25 : 0
4 : 1
3 : 2
-3 : 3
5 : 4
5 : 5
7 : 6
88 : 7
4 : 8
1 : 9
int compare(const void *ptr1, const void *ptr2)
{
const struct Map *aptr = ptr1;
const struct Map *bptr = ptr2;
if (aptr->value == bptr->value)
return (aptr->position > bptr->position) - (aptr->position < bptr->position);
else
return (aptr->value > bptr->value) - (aptr->value < bptr->value);
}
int比较(常量无效*ptr1,常量无效*ptr2)
{
常量结构映射*aptr=ptr1;
常量结构映射*bptr=ptr2;
如果(aptr->value==bptr->value)
返回(aptr->position>bptr->position)-(aptr->positionposition);
其他的
返回(aptr->value>bptr->value)-(aptr->valuevalue);
}
不是一种稳定的分类,没有什么好办法可以绕过这一事实。请参阅,例如查找稳定的排序算法。不过,您必须自己实现它(除非您找到一个为您实现它的库)。您需要扩展您的比较函数以包含第二个结构字段。@YesThatIsMyName不需要它。我认为稳定排序不是您想要的,但是,您更希望基于多个字段进行排序:像常规qsort比较一样,对第一个字段进行三向比较。如果字段相等,则返回比较第二个字段的结果,否则返回比较第一个字段的结果。抱歉,否。我只想按多个字段排序。我怎么能这么做?你知道,你完全正确。在你们说我做了一些研究之后,尽管GNU推荐了用qsort模拟稳定排序的技术,但你们指出的是有意义的。我将收回这一评论。谢谢你让我考虑这件事。