繁体   English   中英

通过在 C 中使用 qsort function 对数据结构进行排序来解决问题

[英]problem by ordering a data structure using the qsort function in C

我需要订购一个数据结构数组,其中包含与节点来源、目的地和权重相关的信息。 问题没有正确排序,因为如果两个值等于 array.originNode 只是取你得到的第一个值而不是应该排序的值。

这就是我的代码对结构进行排序的方式

0 1 30
1 3 22
2 3 20
3 5 20
3 4 15

Process returned 0 (0x0)   execution time : 0.015 s

这是它应该如何订购

0 1 30
1 3 22
2 3 20
3 4 15
3 5 20

我认为问题是我作为参数传递给 qsort 的 function ,它没有进行正确的比较。 如何将我的比较 function 更改为我的代码正确排序结构数组?

这是我的完整代码

#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>

 typedef struct dataNodes{
   int originNode;
   int destinationNode;
   int weight;
   struct dataNodes *next;
} ARRAYS;


  int function (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}


int main() {
ARRAYS array[6];
int n = 5, i;

array [0].originNode = 3;
array [1].originNode = 3;
array[2].originNode = 1;
array[3].originNode = 0;
array[4].originNode = 2;


array [0].destinationNode = 4 ;
array [1].destinationNode = 5;
array[2].destinationNode = 3;
array[3].destinationNode = 1;
array[4].destinationNode = 3;


array [0].weight = 15;
array [1].weight = 20;
array[2].weight = 22;
array[3].weight = 30;
array[4].weight = 20;


              qsort(array,n,sizeof(array[0]),function);
    for(i=0; i<n; i++)
    {
    printf("%d %d %d\n",array[i].originNode,array[i].destinationNode,
    array[i].weight);
    }
return 0;

}

您需要更改比较 function 才能正确比较 ARRAY 记录。 首先比较originNode,如果它们是相同的比较destinationNode。

int function (const void * a, const void * b)
{
    const ARRAYS *ap = a;
    const ARRAYS *bp = b;
    if( ap->originNode < bp->originNode )
        return -1;
    else if( ap->originNode > bp->originNode )
        return 1;
    else if( ap->destinationNode < bp->destinationNode )
        return -1;
    else if( ap->destinationNode > bp->destinationNode )
        return 1;
    else
        return 0;
 }

您正在对 (uh...) ARRAYS的数组进行排序。 因此,您传入的排序 function 应该是比较ARRAYS对象。 您的代码将其视为int

做二次排序,需要在主字段相等的情况下,比较对应的次字段。 对要比较的更多字段执行相同操作。

所以在你的情况下,这种 function 可以为你工作:

int sort_ARRAYS (const void * a, const void * b)
{
    /* the arguments are pointers to ARRAYS objects */
    const ARRAYS *x = a;
    const ARRAYS *y = b;
    int cmp;

    /* primary */
    cmp = x->originNode - y->originNode;
    if (cmp != 0) return cmp;

    /* secondary */
    cmp = x->destinationNode - y->destinationNode;
    if (cmp != 0) return cmp;

    /* tertiary */
    return x->weight - y->weight;
}

来自精美手册

void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *));
[...]
compar参数是一个指向比较 function 的指针,它与两个指向被比较元素的 arguments 一起调用。

因此,您的比较 function 将收到两个ARRAY * arguments 伪装成const void *而您的function只需要适当地转换它们:

int
function(const void * a, const void * b) {
    ARRAYS *aa = (ARRAYS *)a;
    ARRAYS *bb = (ARRAYS *)b;
    return aa->originNode - bb->originNode;
}

如果您想要辅助排序键,请检查是否aa->originNode == bb->originNode并比较辅助键是否为真; 如果需要,对于第三键也是如此。

您当前的代码是偶然的。 这个:

return ( *(int*)a - *(int*)b );

实际上是在比较ARRAYS* arguments 的第一个元素,它之所以有效,是因为(a)结构的开头没有填充,(b) originNode在开头,它实际上是一个int

暂无
暂无

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

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