用C语言中的链表设置交集和差分

用C语言中的链表设置交集和差分,c,singly-linked-list,set-intersection,set-difference,C,Singly Linked List,Set Intersection,Set Difference,我试图得到两个集合的交集和差分,每个集合都由这种形式的单链表表示 struct node{ unsigned n; struct node *next; }; 我已经在前面的任务中编写了这个函数,它计算列表中元素的数量,并确定列表中是否包含某个元素 int cardinality(struct node *s){ struct node *tmp = s; int count = 0; while(tmp != NULL){ tmp = tmp

我试图得到两个集合的交集和差分,每个集合都由这种形式的单链表表示

struct node{
    unsigned n;
    struct node *next;
};
我已经在前面的任务中编写了这个函数,它计算列表中元素的数量,并确定列表中是否包含某个元素

int cardinality(struct node *s){
    struct node *tmp = s;
    int count = 0;

    while(tmp != NULL){
    tmp = tmp->next;
    count++;
    }

    return count;
}

int contains(struct node *s, int v){ /* returns 0 if in list, 1 if not in list */
    struct node *tmp = s;
    int contains = 1;

    while(tmp->next != NULL){
    if(tmp->n == v){
        contains = 0;
        break;
        } else{
        if(tmp == NULL) break;
        tmp = tmp->next;
    }
    }
    return contains;
}
现在我必须编写以下函数,但我不知道如何做。 我是否应该循环一个列表,并对列表中的每个元素循环第二个列表,以检查它是否包含在第二个列表中(差异)?这项任务似乎很复杂,必须有一种更简单的方法来完成。 希望你能帮助我

void intersection(struct node *s1, struct node *s2, struct node **result){

}

void difference(struct node *s1, struct node *s2, struct node **result){

}
下一步实施这些措施:

// Copy one node s, giving the copy a NULL next pointer.
struct node *copy_one(struct node *s);

// Add the given node s to an existing list.
void add(struct node *s, struct node **existing);
这些功能在许多方面都很有用,但在这里您将编写它们:

add(copy_one(s), &existing_list);
来建立你的结果

现在求交的算法是:

set result empty
for all elements e in s1
   if e->val is contained in s2
       add a copy of e to result
对于差异
s1-s2
,它是

set result empty
for all elements e in s1
   if e is _not_ contained in s2
       add a copy of e to result
我会让你算出C。我给你一个完整的答案没有意思

请注意,选择链表来表示集合对于学习C和链表是很好的,但通常不是最好的选择,因为它会导致大型集合的性能降低

我是否应该在一个列表中循环,并针对列表循环中的每个元素循环 通过第二个列表检查是否为(差异) 包含在第二个

如果要将集合表示为未排序的链表,则可以。还有更多 可用于实现集合操作的高效数据结构和算法 (例如,排序数组),但如果这是家庭作业,您可能会被链表卡住

对于这项任务来说,这似乎太复杂了,必须有一种更简单的方法来完成 这个


这是C语言。您需要自己习惯于处理大量低级细节,因为该语言没有提供太多内置数据结构和算法。但是两个嵌套循环其实没什么大不了的。

为什么这两个函数是空的?对我来说,使用返回值来报告结果似乎更符合逻辑,而不是丑陋的第三个参数。@wildplasser实际上,对于设置列表,您可以使用
assign
函数,因此如果有人想用
intersection
的结果覆盖列表,则可以使用
assign(&list,intersection(a,b))
。这些函数基本上完成两项任务:计算一些集合运算和破坏性赋值。不,这种方法对于任务来说并不太复杂。您必须遍历一个列表,并在第二个列表中查找每个项目。您可以为
交叉点
差异
编写一个公共例程,该例程使用一个额外的布尔参数,指示是保留匹配项,还是拒绝。然后,
intersection
difference
只是包装。好消息是:如果对列表进行排序,操作就非常简单了。顺便说一句:OP没有说是否允许更改两个“源”列表。