c语言两个链表的并集,数据结构-两个链表的交集、差集、并集

【题目来自灰灰考研】

(2018南开大学初试)两个有序的无头结点的链表La,Lb。编写函数:如何以最优的方式找出二者的交集,并且把结果存在一个新链表中返回。

单链表的类型定义如下:

Typeddf struct LNode{

Element Type data;

Struct LNode *next;

}LNode, *ListNode;

#include#include#include#define MIN 0xc0c0c0c0

#define MAX 0x3f3f3f3f

using namespace std;

typedef int ElementType;

typedef struct LNode{

ElementType data;

struct LNode *next;

}LNode, *ListNode;

void CreateLinkList(ListNode A, ListNode B)

{

/*

使用指定数组中的数据创建两个链表

*/

int n = 6, m = 6;

ElementType dataA[] = {1, 2, 3, 7, 8, 10};

ElementType dataB[] = {1, 3, 5, 7, 9, 11};

LNode *p, *q;

p = A;

p->data = dataA[0];

p->next = NULL;

for(int i = 1; i < n; i++)

{

q = (LNode*)malloc(sizeof(LNode));

q->data = dataA[i];

p->next = q;

p = p->next;

p->next = NULL;

}

p = B;

p->data = dataB[0];

p->next = NULL;

for(int i = 1; i < m; i++)

{

q = (LNode*)malloc(sizeof(LNode));

q->data = dataB[i];

p->next = q;

p = p->next;

p->next = NULL;

}

}

ListNode intersection(ListNode A, ListNode B)

{

/*

找到两个链表的交集

思路:

依次遍历两个链表,比较两个链表当前元素的大小关系

1。如果两个链表当前元素相等,则找到一个相交元素

2。如果第一个链表元素小于第二个链表元素,则第一个链表的指针后移一位

3。如果第一个链表元素大于第二个链表元素,则第二个链表的指针后移一位

*/

ListNode C = (ListNode)malloc(sizeof(ListNode));

C->next = NULL;

LNode *p, *q, *r;

p = A;

q = B;

r = C;

while(p!=NULL && q!=NULL)

{

if(p->data < q->data)

{

p = p->next;

}

else if(p->data == q->data)

{

LNode *s = (LNode*)malloc(sizeof(LNode));

s->next = NULL;

s->data = p->data;

p = p->next;

q = q->next;

r->next = s;

r = s;

}

else

{

q = q->next;

}

}

return C->next;

}

ListNode Union(ListNode A, ListNode B)

{

/*

找到两个链表的并集(去除相同元素)

思路:

首先使用一个指针last记录上次合并进来的新元素

依次遍历两个链表,比较两个链表当前元素的大小关系

1。如果两个链表当前元素相等,则比较last和当前元素的关系,如果不相同则将当前元素并入到新的链表中,两指针均后移。如果相同则只是移动两指针

2。如果第一个链表元素小于第二个链表元素,则第一个链表当前元素和last比较,如果不同则加入,并后移第一个链表指针 。如果相同则只是移动第一个指针

3。如果第一个链表元素大于第二个链表元素,则第二个链表当前元素和last比较,如果不同则加入,并后移第二个链表指针 。如果相同则只是移动第二个指针

4。如果两个链表中某个还有剩余,则与last比较...

*/

ListNode F = (ListNode)malloc(sizeof(ListNode));

F->next = NULL;

F->data = MAX;

LNode *p, *q, *r, *last;

p = A;

q = B;

r = F;

last = F;

while(p!=NULL && q!=NULL)

{

if(p->data < q->data)

{

if(p->data != last->data)

{

LNode *s = (LNode*)malloc(sizeof(LNode));

s->next = NULL;

s->data = p->data;

r->next = s;

last = p;

r = s;

}

p = p->next;

}

else if(p->data == q->data)

{

if(p->data != last->data)

{

LNode *s = (LNode*)malloc(sizeof(LNode));

s->next = NULL;

s->data = p->data;

r->next = s;

last = p;

r = s;

}

p = p->next;

q = q->next;

}

else

{

if(q->data != last->data)

{

LNode *s = (LNode*)malloc(sizeof(LNode));

s->next = NULL;

s->data = q->data;

r->next = s;

last = q;

r = s;

}

q = q->next;

}

}

if(q != NULL)

p = q;

while(p != NULL)

{

if(p->data != last->data)

{

LNode *s = (LNode*)malloc(sizeof(LNode));

s->next = NULL;

s->data = p->data;

r->next = s;

last = p;

r = s;

}

p = p->next;

}

return F->next;

}

ListNode Difference(ListNode A, ListNode B)

{

/*

找到两个链表的差集

思路:

依次遍历两个链表,比较两个链表当前元素的大小关系

1。如果两个链表当前元素相等,则两个链表的指针均后移一位

2。如果第一个链表元素小于第二个链表元素,则第一个链表的元素肯定是独有的,所有加入到结果链表中

3。如果第一个链表元素大于第二个链表元素,则第二个链表的指针后移一位

*/

ListNode D = (ListNode)malloc(sizeof(ListNode));

D->next = NULL;

LNode *p, *q, *r;

p = A;

q = B;

r = D;

while(p!=NULL && q!=NULL)

{

if(p->data < q->data)

{

LNode *s = (LNode*)malloc(sizeof(LNode));

s->next = NULL;

s->data = p->data;

p = p->next;

r->next = s;

r = s;

}

else if(p->data == q->data)

{

p = p->next;

q = q->next;

}

else

{

q = q->next;

}

}

while(p != NULL)

{

LNode *s = (LNode*)malloc(sizeof(LNode));

s->next = NULL;

s->data = p->data;

p = p->next;

r->next = s;

r = s;

}

return D->next;

}

int main()

{

ListNode A, B, C, D, E, F, q;

A = (ListNode)malloc(sizeof(ListNode));

B = (ListNode)malloc(sizeof(ListNode));

//C为两个链表的交集

CreateLinkList(A, B);

C = intersection(A, B);

q = C;

while(q!=NULL)

{

cout

}

cout

}

cout

}

cout

}

cout<

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个用链表和 C 语言实现计算集合的交集并集差集和补集的代码: ```c #include <stdio.h> #include <stdlib.h> // 定义链表结点 typedef struct Node { int value; struct Node *next; } Node; // 定义链表头结点 typedef struct { Node *head; Node *tail; } List; // 初始化链表 void initList(List *list) { list->head = NULL; list->tail = NULL; } // 在链表尾部插入一个新结点 void insert(List *list, int value) { Node *newNode = (Node *) malloc(sizeof(Node)); newNode->value = value; newNode->next = NULL; if (list->head == NULL) { list->head = newNode; } else { list->tail->next = newNode; } list->tail = newNode; } // 判断链表中是否存在某个元素 int find(List *list, int value) { Node *p = list->head; while (p != NULL) { if (p->value == value) { return 1; } p = p->next; } return 0; } // 链表交集运算 List intersection(List *list1, List *list2) { List result; initList(&result); Node *p1 = list1->head; while (p1 != NULL) { if (find(list2, p1->value)) { insert(&result, p1->value); } p1 = p1->next; } return result; } // 链表并集运算 List unionSet(List *list1, List *list2) { List result; initList(&result); Node *p1 = list1->head; while (p1 != NULL) { insert(&result, p1->value); p1 = p1->next; } Node *p2 = list2->head; while (p2 != NULL) { if (!find(&result, p2->value)) { insert(&result, p2->value); } p2 = p2->next; } return result; } // 链表差集运算 List difference(List *list1, List *list2) { List result; initList(&result); Node *p1 = list1->head; while (p1 != NULL) { if (!find(list2, p1->value)) { insert(&result, p1->value); } p1 = p1->next; } return result; } // 链表的补集运算 List complement(List *list1, List *list2) { List result; initList(&result); Node *p1 = list1->head; while (p1 != NULL) { if (!find(list2, p1->value)) { insert(&result, p1->value); } p1 = p1->next; } Node *p2 = list2->head; while (p2 != NULL) { if (!find(list1, p2->value)) { insert(&result, p2->value); } p2 = p2->next; } return result; } // 打印链表中的元素 void printList(List *list) { Node *p = list->head; while (p != NULL) { printf("%d ", p->value); p = p->next; } printf("\n"); } int main() { List list1, list2; initList(&list1); initList(&list2); insert(&list1, 1); insert(&list1, 2); insert(&list1, 3); insert(&list2, 2); insert(&list2, 3); insert(&list2, 4); printf("List 1: "); printList(&list1); printf("List 2: "); printList(&list2); printf("Intersection: "); List result1 = intersection(&list1, &list2); printList(&result1); printf("Union: "); List result2 = unionSet(&list1, &list2); printList(&result2); printf("Difference (list1 - list2): "); List result3 = difference(&list1, &list2); printList(&result3); printf("Complement: "); List result4 = complement(&list1, &list2); printList(&result4); return 0; } ``` 在上述代码中,我们定义了链表结点类型 `Node` 和链表类型 `List`,其中 `List` 包含链表头结点和尾结点。我们使用 `initList` 函数初始化链表,使用 `insert` 函数在链表尾部插入一个新结点。`find` 函数用于判断链表中是否存在某个元素。 我们实现了四个函数:`intersection`、`unionSet`、`difference` 和 `complement`,分别用于计算集合的交集并集差集和补集。这些函数都返回一个链表类型的结果。最后,我们使用 `printList` 函数打印链表中的元素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值