简体   繁体   English

按C中第二个字段排序结构数组

[英]Sorting array of structs by second field in C

My professor recommended us to use qsort() to sort an array of structs. 我的教授建议我们使用qsort()对结构数组进行排序。 However, I have to come to find out that it is not stable. 但是,我必须找出它是不稳定的。 I know there are other posts about this topic, but none seem to give an easy fix to stabilize my sort. 我知道还有关于此主题的其他文章,但是似乎没有一个简单的方法可以稳定我的排序。 Is there a way that I could use qsort() for a second data field? 有没有一种方法可以将qsort()用于第二个数据字段?

Here is my code: 这是我的代码:

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

The output now is: 现在的输出是:

-3 : 3
1 : 9
3 : 2
4 : 8
4 : 1
5 : 5
5 : 4
7 : 6
25 : 0
88 : 7

How can I maintain the order of the duplicates? 如何维护重复项的顺序? I spent a lot of time trying to figure out qsort() and so I'd like to keep it if possible. 我花了很多时间试图弄清楚qsort() ,所以我想尽可能保留它。

EDIT I wasn't clear on the output I'm trying to get. 编辑我不清楚我想要得到的输出。 Before sorting, the array of structs contains a value and the index of that value. 在排序之前,结构数组包含一个值和该值的索引。 So, the original array of structs looked like this: 因此,原始的结构数组如下所示:

 25 : 0
  4 : 1
  3 : 2
 -3 : 3
  5 : 4
  5 : 5
  7 : 6
 88 : 7
  4 : 8
  1 : 9

After sorting, my code printed the above. 排序后,我的代码打印了上面。 However, what I was hoping for was this: 但是,我希望的是:

-3 : 3
1 : 9
3 : 2
4 : 1
4 : 8
5 : 4
5 : 5
7 : 6
25 : 0
88 : 7

Where if the values in the first field are equal, then they need to be sorted by values in the second field, which will never be equal because they are the indexes. 如果第一个字段中的值相等,则需要按第二个字段中的值对它们进行排序,因为它们是索引,所以永远不会相等。

Since the struct has a position member that represents the initial array ordering, you can easily emulate a stable sort. 由于该结构具有一个表示初始数组顺序的position成员,因此您可以轻松地模拟稳定的排序。 In the comparison function, if the two value members are equal, then return an ordering based on the position members, like this: 在比较函数中,如果两个value成员相等,则根据position成员返回顺序,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM