C链接列表添加订购

时间:2010-11-02 18:22:33

标签: c linked-list compare

我有一个链接的List c文件/ head作为我用于项目的独立库。我还没有在库中添加有序的方法。我的问题是编写比较函数,因为我想比较不同项目的不同项目。如何在我的main中为我正在使用的任何项目创建一个比较函数,然后传递并将该函数用于我的链表库中的add_ordered方法?我似乎无法找到一个可行的解决方案来传递函数并在我的链表中使用它。

这是我的add_ordered和compareto方法的未编译版本(与每种文件的方法比较不同):

void ll_add_ordered(ll_node *head, void *d){
 ll_node *cur;
 ll_node *temp;

 if(head->size == 0){
  ll_add_first(head, d);
 }else{
  temp = (ll_node *)malloc(sizeof(ll_node));
  temp->data = d;

  for(cur = head->next; cur->data != NULL && compareTo(temp->data, cur->data); cur = cur->next)
   ;

  temp->next = cur;
  temp->prev = cur->prev;
  cur->prev->next = temp;
  cur->prev = temp;

  head->size++;
 }
}

int compareTo(proc *first, proc *second){
 if(first->arrival < second->arrival)
  return -1;
 else if(first->arrival > second->arrival)
  return 1;
 else
  return 0;
}

3 个答案:

答案 0 :(得分:1)

一种方法是传入指向带* *参数的函数的指针,例如。 int(* cmp)(void * lhs,void * rhs)。在这种情况下,cmp的责任是将其参数转换为正确的类型。

你可能能够通过宏和令牌粘贴做一些更安全的东西,但我个人觉得这样做太过分了。如果要实例化链接列表,那么您就知道这些类型是什么,并且可以通过合适的比较函数传递。

答案 1 :(得分:1)

这将定义一个名为compareFunc的类型:

typedef int(*compareFunc)(void *first, void *second);

现在你要将ll_add_ordered重写为:

void ll_add_ordered(ll_node *head, void *d, compareFunc compareTo) { . . .

这将允许您将与compareTo函数签名匹配的任何函数传入ll_add_ordered并在进行比较时调用它。

答案 2 :(得分:0)

一个简单的解决方案是使用函数指针,并将指针传递给函数。

我建议您为函数签名声明一个别名,以免在一段时间后发疯:)

我假设ll_node.data的类型为void *。因此,您的链接列表需要两件事:

  1. 比较函数接受两个void指针,比较它们(使用内幕知识)。比较函数必须知道如何处理数据。当然,对于呼叫ll_add_ordered的人/代码/邪恶的同事,这个要求是隐含的。
  2. 比较函数返回1,0或-1。
  3. 此类函数指针的类型别名为:

    typedef int (*ll_comp_func)(void *, void*);
    

    如果你认为这看起来很疯狂,那你就完全正确了。当没有任何作用时,它可以让你<罢工>疯狂凶杀的深夜。无论如何,它真正做的是为函数指针创建一个typedef,并调用别名ll_comp_func

    然后,您可以将ll_add_ordered更改为以下格式:

    void ll_add_ordered(ll_node *head, void *d, ll_comp_func comparison){
       // Do stuff.
       int order = comparison(temp->data, cur->data);
       // Do even more stuff.
    }