我目前正在图上实现一些算法,我使用一个结构来保存图中每个边的信息:它的源顶点,它的目标顶点和它的权重。
我的结构声明如下:
typedef struct edge {
int data[3]; //src, dest, weight
} edge_t, *edge_p;
然后我创建一个变量指针并为n
结构分配内存,其中n
是图中的多个边:
edge_p localEdges = (edge_p)malloc(n*sizeof(edge_t));
然后我用相同类型的另一个struct localEdges
的值填充struct allEdges
:
for (int i = 0; i < num_edges; i++) {
localEdges[i].data[0] = allEdges[i].data[0];
localEdges[i].data[1] = allEdges[i].data[1];
localEdges[i].data[2] = allEdges[i].data[2];
}
然后我需要按数据[2]字段的升序(按上升边权重)对localEdges
的内容进行排序。我的比较功能是:
int myComp (const void *a, const void *b)
{
const edge_t * ptr_a = (const edge_t *)a;
const edge_t * ptr_b = (const edge_t *)b;
return ptr_b->data[2] < ptr_a->data[2];
}
该函数的调用如下:
qsort(localEdges, n, sizeof(edge_t), myComp);
然而,这不起作用。已处理的localEdges
数组错误地放置了一些数据。例如:
localEdges[0].data[2] = 1
localEdges[1].data[2] = 2
localEdges[2].data[2] = 1
localEdges[3].data[2] = 2
localEdges[4].data[2] = 3
localEdges[5].data[2] = 3
localEdges[6].data[2] = 4
应该是:
localEdges[0].data[2] = 1
localEdges[1].data[2] = 1
localEdges[2].data[2] = 2
localEdges[3].data[2] = 2
localEdges[4].data[2] = 3
localEdges[5].data[2] = 3
localEdges[6].data[2] = 4
我想有一些指针,但我对它们并不十分自信。
有什么建议吗?我会感谢你的帮助。
答案 0 :(得分:3)
简而言之:您的比较功能是错误的。引用a qsort()
manual:
如果第一个参数被认为分别小于,等于或大于第二个参数,则比较函数必须返回小于,等于或大于零的整数。如果两个成员比较相等,则它们在排序数组中的顺序是未定义的。
因此,如果您返回0
,则认为这两个元素相等。
return ptr_b->data[2] < ptr_a->data[2];
如果0
中的值大于*ptr_b
中的值,则此行会返回*ptr_a
。
正确的方法如下:
int myComp (const void *a, const void *b)
{
const edge_t * ptr_a = (const edge_t *)a;
const edge_t * ptr_b = (const edge_t *)b;
if (ptr_a->data[2] < ptr_b->data[2]) return -1;
if (ptr_a->data[2] > ptr_b->data[2]) return 1;
return 0;
}
答案 1 :(得分:2)
来自C标准(7.22.5.2 qsort功能)
3数组的内容按升序排序 到compar指向的比较函数,调用它 两个指向被比较对象的参数。 功能 如果,则返回小于,等于或大于零的整数 第一个参数被认为分别小于,相等 到,或大于第二个。
因此定义函数,例如以下方式
int myComp (const void *a, const void *b)
{
const edge_t * ptr_a = (const edge_t *)a;
const edge_t * ptr_b = (const edge_t *)b;
return ( ptr_b->data[2] < ptr_a->data[2] ) - ( ptr_a->data[2] < ptr_b->data[2] );
}
答案 2 :(得分:0)
您的比较器功能似乎未正确实现。它永远不会返回负面结果,只是将bool值(比较操作)转换为0和1.你能尝试类似的东西:
int myComp (const void *a, const void *b)
{
const edge_t * ptr_a = (const edge_t *)a;
const edge_t * ptr_b = (const edge_t *)b;
return (ptr_b->data[2] < ptr_a->data[2]) ? -1 :
(ptr_b->data[2] > ptr_a->data[2]) ? 1 : 0;
}