重用比较功能

时间:2013-08-09 12:11:01

标签: c void-pointers avl-tree qsort

我使用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 **

2 个答案:

答案 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。一样,如果您使用的是C99cmp可能是static inline个功能

答案 1 :(得分:1)

你不能使用完全相同的功能,但你可以用第一个来定义第二个:

int cmp2(const void *pa, const void *pb)
{
    return cmp(*(void **)pa, *(void **)pb);
}