我使用AVL构建了一个二叉树,然后将数据打包在一个数组中
typedef struct {
void **data;
int count;
} t_table;
比较功能如下:
int cmp(const void *pa, const void *pb)
{
int a = *(int *)pa;
int b = *(int *)pb;
if (a > b)
return +1;
else
if (b > a)
return -1;
else
return 0;
}
我在avl-tree中插入并使用K&R qsort排序指针数组没有问题。
现在我想使用qsort
的sandard函数<stdlib.h>
,但我被迫使用t_table
的新函数(由于qsort
需要指针转换) ,它看起来像:
int cmp(const void *pa, const void *pb)
{
int a = *(int*)(*(void**)pa);
int b = *(int*)(*(void**)pb);
if (a > b)
return +1;
else
if (b > a)
return -1;
else
return 0;
}
我理解为什么必须更改该功能(引用C-FAQ):
理解qsort中好奇指针转换的原因 比较函数是必要的(为什么演员的功能 调用qsort时的指针无法帮助),思考如何有用 qsort有效。 qsort对类型或类型一无所知 正在排序的数据的表示:它只是随机播放 小块的记忆。 (所有它知道的块是他们的大小, 你在qsort的第三个参数中指定的。)确定是否有两个 块需要交换,qsort调用你的比较函数。 (互换 它们,它使用相当于memcpy。)
但我想知道是否有任何替代方法(使用stdlib qsort
)以避免必须维护两个比较函数(一个用于avl而另一个用于void **
)
答案 0 :(得分:2)
我不确定你是否真的可以避免维护这两个功能,但你可以这样做:
int cmp_int(const void *pa, const void *pb)
{
int a = *(int *)pa;
int b = *(int *)pb;
return cmp(a, b);
}
int cmp_voidp(const void *pa, const void *pb)
{
int a = *(int*)(*(void**)pa);
int b = *(int*)(*(void**)pb);
return cmp(a, b);
}
static int cmp(const int a, const int b)
{
if (a > b)
return +1;
else
if (b > a)
return -1;
else
return 0;
}
你有3个功能,但你不重复自己,而且维护起来更容易。
编辑:与 Sergey L。一样,如果您使用的是C99
,cmp
可能是static inline
个功能
答案 1 :(得分:1)
你不能使用完全相同的功能,但你可以用第一个来定义第二个:
int cmp2(const void *pa, const void *pb)
{
return cmp(*(void **)pa, *(void **)pb);
}