Problem A: 求集合的交并补集
Time Limit: 1 Sec Memory Limit: 4 MBDescription
任意给定两个包含1-30000个元素的集合A,B(集合中元素类型为任意整型数,且严格递增排列),求A交B、A并B、A-B和B-A集合。
Input
输入第一行为测试数据组数。每组测试数据两行,分别为集合A、B。每行第一个数n(1<=n<=30000)为元素数量,后面有n个严格递增的绝对值小于2^31代表集合中包含的数。
Output
对每组测试数据输出5行,第1行为数据组数,后4行分别为按升序输出两个集合的A交B、A并B、A-B和B-A集合。格式见样例。
Sample Input
1
3 1 2 5
4 2 3 5 8
3 1 2 5
4 2 3 5 8
Sample Output
Case #1:
2 5
1 2 3 5 8
1
3 8
2 5
1 2 3 5 8
1
3 8
HINT
考察知识点:有序表合并,时间复杂度O(n),空间复杂度O(n)
做法:
1、用单链表实现
2、详细实现看注释
注意:
1、所给数据本身就是严格递增,无需排序
AC代码(C语言格式写的,但是用C++交的):
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;//定义数据项类型
typedef struct node * PNode;//定义节点指针
//节点的定义
typedef struct node{
ElemType data; //数据域
PNode next; //链域
}LNode,*LinkList;
//构造一个空的单链表
int InitList(LinkList *L)
{
(*L) = (LinkList)malloc(sizeof(LNode));
if ((*L) == NULL)
return -1;
(*L)->next = NULL;
return 0;
}
//构造一个新的节点
int NewNode(PNode *p)
{
(*p) = (PNode)malloc(sizeof(LNode));
if ((*p) == NULL)
return -1;
(*p)->next = NULL;
return 0;
}
//单链表取值
int GetElem(LinkList L,int i,ElemType *e)
{
PNode p = NULL;
p = L->next;
int j = 1;
while(p && j<i)
{
p = p->next;
++j;
}
if (!p || j>i) return -1;
*e = p->data;
return 0;
}
//查找 找到返回此元素地址 未找到返回NULl
PNode LocateElem(LinkList L,ElemType e)
{
PNode p = NULL;
p = L->next;
while(p && p->data != e)
p = p->next;
return p;
}
//在第i个位置 插入节点
int ListInsert(LinkList L,int i,ElemType e)
{
PNode p = L;
int j = 0;
while(p && j<(i-1))
{
p = p->next;
++j;
}
if (!p || j>i-1) return -1;
PNode s;
if (NewNode(&s) == -1)
return -1;
s->data = e;
s->next = p->next;
p->next = s;
return 0;
}
//删除 第i个节点
int ListDelete(LinkList L,int i)
{
PNode p = L;
int j = 0;
while((p->next) && (j<i-1))
{
p = p->next;
++j;
}
if (!(p->next) || (j>i-1))
return -1;
PNode q = p->next;
p->next = q->next;
free(q);
return 0;
}
//前插法创建单链表
void CreateList_H(LinkList *L,int n)
{
InitList(L); //创建空链表头
int i;
PNode p = NULL;
for (i=0;i<n;i++)
{
NewNode(&p);
scanf("%d",&(p->data));
p->next = (*L)->next; (*L)->next = p;
}
}
//后插法创建单链表
void CreateList_R(LinkList *L,int n)
{
InitList(L); //创建空链表头
int i;
PNode p = NULL;
PNode r = (*L); //r为尾指针(指向最后一个节点)
for (i=0;i<n;i++)
{
NewNode(&p);
scanf("%d",&(p->data));
p->next = NULL; r->next = p;
r = p;
}
}
//清除整个链表
int Clear(LinkList *L)
{
PNode p,delp;
p = (*L);
while(p->next)
{
delp = p;
p = p->next;
free(delp);
}
free(p);
(*L) = NULL;
return 0;
}
LinkList LA = NULL;
LinkList LB = NULL;
void Bing()
{
int conid = 0;
PNode pa,pb;
pa = LA;
pb = LB;
pa = pa->next;
pb = pb->next;
while(pa && pb)
{
if (pa->data < pb->data) //pa小,输出
{
if (conid == 0) //第一次输出
{
printf("%d",pa->data);
conid = 1;
}
else
printf(" %d",pa->data);
pa = pa->next; //pa后移
}
else if (pa->data > pb->data) //pb小,输出
{
if (conid == 0) //第一次输出
{
printf("%d",pb->data);
conid = 1;
}
else
printf(" %d",pb->data);
pb = pb->next; //pb后移
}
else //pa->data == pb->data
{
if (conid == 0) //第一次输出
{
printf("%d",pa->data);
conid = 1;
}
else
printf(" %d",pa->data);
pa = pa->next; //pa后移
pb = pb->next; //pb后移
}
}
if (pa != NULL)
{
while(pa)
{
if (conid == 0) //第一次输出
{
printf("%d",pa->data);
conid = 1;
}
else
printf(" %d",pa->data);
pa = pa->next;
}
}
if (pb != NULL)
{
while(pb)
{
if (conid == 0) //第一次输出
{
printf("%d",pb->data);
conid = 1;
}
else
printf(" %d",pb->data);
pb = pb->next;
}
}
}
void Jiao()
{
int conid = 0;
PNode pa,pb;
pa = LA;
pb = LB;
pa = pa->next;
pb = pb->next;
while(pa && pb)
{
if (pa->data < pb->data) //pa小
pa = pa->next; //pa后移
else if (pa->data > pb->data) //pb小
pb = pb->next; //pb后移
else //pa->data == pb->data
{
if (conid == 0) //第一次输出
{
printf("%d",pa->data);
conid = 1;
}
else
printf(" %d",pa->data);
pa = pa->next; //pa后移
pb = pb->next; //pb后移
}
}
}
void A_B()
{
int conid = 0;
PNode pa,pb;
pa = LA;
pb = LB;
pa = pa->next;
pb = pb->next;
while(pa && pb)
{
if (pa->data < pb->data) //pa小,输出
{
if (conid == 0) //第一次输出
{
printf("%d",pa->data);
conid = 1;
}
else
printf(" %d",pa->data);
pa = pa->next; //pa后移
}
else if (pa->data > pb->data) //pb小,输出
{
pb = pb->next; //pb后移
}
else //pa->data == pb->data
{
pa = pa->next; //pa后移
pb = pb->next; //pb后移
}
}
if (pa != NULL)
{
while(pa)
{
if (conid == 0) //第一次输出
{
printf("%d",pa->data);
conid = 1;
}
else
printf(" %d",pa->data);
pa = pa->next;
}
}
}
void B_A()
{
int conid = 0;
PNode pa,pb;
pa = LA;
pb = LB;
pa = pa->next;
pb = pb->next;
while(pa && pb)
{
if (pa->data < pb->data) //pa小,输出
{
pa = pa->next; //pa后移
}
else if (pa->data > pb->data) //pb小,输出
{
if (conid == 0) //第一次输出
{
printf("%d",pb->data);
conid = 1;
}
else
printf(" %d",pb->data);
pb = pb->next; //pb后移
}
else //pa->data == pb->data
{
pa = pa->next; //pa后移
pb = pb->next; //pb后移
}
}
if (pb != NULL)
{
while(pb)
{
if (conid == 0) //第一次输出
{
printf("%d",pb->data);
conid = 1;
}
else
printf(" %d",pb->data);
pb = pb->next;
}
}
}
int main()
{
int T;
scanf("%d",&T);
for (int i=0;i<T;i++)
{
InitList(&LA); //创建链表头
InitList(&LB); //创建链表头
int n;
scanf("%d",&n);
CreateList_R(&LA,n); //读n个数据后接到链表
scanf("%d",&n);
CreateList_R(&LB,n); //读n个数据后接到链表
printf("Case #%d:\n",i+1);
Jiao();
printf("\n");
Bing();
printf("\n");
A_B();
printf("\n");
B_A();
printf("\n");
Clear(&LA); //清空数据
Clear(&LB);
}
return 0;
}