代码部分有参考
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
#define OK 1
typedef int Status; //要加分号
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
} LNode, *LinkList;
//创建空链表
Status Init_LinkList(LinkList &L)
{
LinkList p;
p = (LinkList)malloc(sizeof(LNode));
if (!p)
return ERROR;
L = p;
L->next = NULL;
return OK;
}
int x, y;
void show()
{
printf("\t\t*********单链表的集合运算************\n");
printf("\n");
printf("\t\t\t1. 集合A数据输入\n");
printf("\t\t\t2. 集合B数据输入\n");
printf("\t\t\t3. 集合A和集合B的并集\n");
printf("\t\t\t4. 集合A和集合B的交集\n");
printf("\t\t\t5. 集合A和集合B的差集\n");
printf("\t\t\t0. 退出系统\n");
printf("\n");
printf("\t\t*********单链表的集合运算*************\n");
printf("\n");
}
// 输入
Status input(LinkList &L, int n)
{
LinkList p, tc;
int i;
tc = L;
printf("请输入元素:\n");
for (i = 1; i <= n; i++)
{
p = (LinkList)malloc(sizeof(LNode));
if (p != NULL)
{
scanf("%d", &p->data);
p->next = L->next; //头插法
tc->next = p;
tc = p;
}
else
return ERROR;
}
tc->next = NULL;
printf("集合输入完成!\n");
return OK;
}
//输出
void Output(LinkList L)
{
LinkList p; //定义一个指针p
//p=(LinkList)malloc(sizeof(LNode));
if (L->next == NULL)
printf("该链表是空链表!\n");
else
{
for (p = L->next; p != NULL; p = p->next)
printf("%d ", p->data);
printf("\n");
}
}
//实现链表的清空
Status ClearList_L(LinkList &L)
{
LinkList p, q; //定义两个指针p,q
p = L->next;
if (!p) //如果p指向的链表L是一个空表 就直接返回OK
return OK;
while (p) //当p指向的链表L不是空表 则进行以下语句,赋给另外一个指针
{
q = p;
p = p->next;
free(q); //释放链表结点的空间
}
L->next = NULL; //将L链表的next指针域 置为 NULL 空
return OK;
}
//并集 (先清空C,C中的数据会在后面的循环中不断插入!就是A与C找比较,C中没有A的就插入;B与C找比较,C中没有B的就插入(遍历完,即==NULL的时候插入))
void bingji(LinkList La, LinkList Lb, LinkList &Lc)
{
if (Lc->next != NULL) //如果Lc链表不为空则就要进行链表清空
ClearList_L(Lc);
LinkList p, q, s; //p指针用来遍历A,B q用来控制C的结点
//对链表A插入C中
p = La->next; //指针p控制扫描La的每一个结点(元素)
while (p)
{
q = Lc->next;
while (q && (q->data != p->data)) //C中不为空,且数据不相等时,向下继续进行
q = q->next;
if (q == NULL) //当q遍历完一次都没有找到的话,即q的最后为空时就可以将A中的一个元素插入C中
{
s = (LinkList)malloc(sizeof(LNode)); //s指针用来控制C中的数据
s->data = p->data; //头插法
s->next = Lc->next;
Lc->next = s;
}
p = p->next;
}
//对链表B插入C中
p = Lb->next; //指针p控制扫描Lb的每一个结点(元素)
while (p)
{
q = Lc->next;
while (q && (q->data != p->data)) //C中不为空,且数据不相等
q = q->next;
if (q == NULL) //当q遍历完一次都没有找到的话,即q的最后为空时就可以将B中的一个元素插入C中
{
s = (LinkList)malloc(sizeof(LNode)); //s指针用来控制C中的数据
s->data = p->data; //头插法
s->next = Lc->next;
Lc->next = s;
}
p = p->next;
}
}
//交集 (先清空C链表,再A与B中找相同的break(不为空,记录),再与C中比较(与并集同理插入)插入C中即可)
void jiaoji(LinkList La, LinkList Lb, LinkList &Lc)
{
LinkList p, q, s, k; //p遍历A,q遍历B,s遍历C,k是赋值指针
if (Lc->next)
ClearList_L(Lc);
//A
p = La->next;
while (p) //A中不为空时
{
q = Lb->next;
while (q)
{
if (p->data == q->data) //找到了就可以break,也可以定义t进行计数操作,但是这样不好计算链表长度,当然也可以定义全局变量
break;
else
q = q->next;
}
if (q) //p不为空
{
s = Lc->next;
//寻找C中是否含有相同数据
while (s)
{
if (s->data == p->data)
break;
else
s = s->next;
}
if (s == NULL)
{
k = (LinkList)malloc(sizeof(LNode));
k->data = p->data;
k->next = Lc->next;
Lc->next = k;
}
}
p = p->next;
}
}
//差集 (先清空C后,找A中与B中不同的,找到B最后,即==NULL的时候插入即可!)
void chaji(LinkList La, LinkList Lb, LinkList &Lc)
{
LinkList p, q, s, k;
if (Lc->next)
ClearList_L(Lc);
p = La->next;
while (p != NULL)
{
q = Lb->next;
while (q != NULL)
{
if (q->data == p->data)
break;
else
q = q->next;
}
if (q == NULL)
{
s = Lc->next;
//寻找C中是否含有相同数据
while (s != NULL)
{
if (s->data == p->data)
break;
else
s = s->next;
}
if (s == NULL)
{
k = (LinkList)malloc(sizeof(LNode));
k->data = p->data;
k->next = Lc->next;
Lc->next = k;
}
}
p = p->next;
}
}
int main()
{
//定义
int choice;
LinkList La, Lb, Lc;
//初始化
Init_LinkList(La);
Init_LinkList(Lb);
Init_LinkList(Lc);
//功能
while (1)
{
show();
printf("请输入要选择的功能:\n");
scanf("%d", &choice);
switch (choice)
{
case 1:
ClearList_L(La);
printf("请输入集合A要插入的个数:\n");
scanf("%d", &x);
input(La, x);
printf("集合A为:\n");
Output(La);
getchar();
getchar();
break;
case 2:
ClearList_L(Lb);
printf("请输入集合B要插入的个数:\n");
scanf("%d", &y);
input(Lb, y);
printf("集合B为:\n");
Output(Lb);
printf("请按回车继续!\n");
getchar();
getchar();
break;
case 3:
printf("集合A与集合B的并集为:\n");
bingji(La, Lb, Lc);
Output(Lc);
printf("请按回车继续!\n");
getchar();
getchar();
break;
case 4:
printf("集合A与集合B的交集为:\n");
jiaoji(La, Lb, Lc);
Output(Lc);
printf("请按回车继续!\n");
getchar();
getchar();
break;
case 5:
printf("集合A与集合B的并集为:\n");
chaji(La, Lb, Lc);
Output(Lc);
printf("请按回车继续!\n");
getchar();
getchar();
break;
case 0:
printf("成功退出系统!\n");
exit(0);
getchar();
getchar();
break;
default:
printf("输入有误!\n");
exit(0);
break;
}
}
return 0;
}
单链表实现集合交并补
最新推荐文章于 2024-07-24 20:25:39 发布