目录
题目内容
如果以单链表表示集合,假设集合A用单链表LA表示,集合B用单链表LB表示,设计算法求两个集合的差,即A-B。
算法分析
本设计使用单链表实现。
由集合算法的规则可知,集合的差A-B中包含所有属于集合A而不属于集合B的元素。具体做法:先定义结构体类型,然后用尾插法建立空表用于存储集合A和集合B,在设计差集运算时,从集合A的第一个元素开始遍历,寻找元素e,对于集合A中每一个元素e,在集合B的链表LB中进行查找,若存在与e相同的元素,则从LA中将其删除,若不同,则将元素留在集合A中,最后A-B的结果保留在集合A中。
概要设计
函数类型
- 函数CreateList()用来尾插法建立单链表
- 函数Difference()用来进行集合A与集合B的差集运算
- 主函数main()
算法流程图
源代码
/**
*@author :sy
*@data:2021-10-1
*@version:1.0
*@Description:求两个集合的差
*/
#include<stdio.h>
#include<stdlib.h>
typedef struct Linklist
{
int elem; //存储链表结点的元素值
struct Linklist *next; //指向后继节点
}LinkList; //单链表结点类型
/*尾插法建立单链表*/
LinkList *CreateList(int n)
{
LinkList *L,*p,*q;
int i;
L=(LinkList*)malloc(sizeof(LinkList)); //为头结点分配空间
p=L; //尾指针指向表尾
scanf("%d",&(p->elem));
p->next=NULL; //建带头结点的空链表
/*将数据元素依次插入到表尾形成单链表*/
for(i=1;i<n;i++)
{
q=(LinkList*)malloc(sizeof(LinkList)); //为读入的字符分配存储空间
scanf("%d",&(q->elem));
q->next=NULL; //插入表尾
p->next=q;
p=q;
}
return L; //返回单链表
}
/*求两个集合的差集,计算结果保存在集合A中*/
LinkList *Difference(LinkList *A,LinkList *B)
{
LinkList *la,*pre,*lb;
int e,flag;
la=A;
pre=A;
while(la!=NULL) //遍历链表A中每一个元素
{
flag=0;
e=la->elem ;
lb=B; //对A中的每一个元素e,都从LB的表头开始查找
while(lb!=NULL)
{
if(lb->elem==e) //若A中的元素也在B中存在,则删除A中的该元素
{
if(la==A) //pa是表头
{
A=la->next;
pre=la->next ;
la=la->next ;
flag=1;
}
else if(la->next==NULL) //pa是表尾
{
la=NULL;
pre->next=la;
flag=1;
}
else //非表头元素和非表尾元素
{
pre->next =la->next ;
la=la->next ;
flag=1;
}
break;
}
else
{
lb=lb->next ;
}
}
if(flag==0)
{
pre=la;la=la->next ;
}
return A; //计算结果保存在集合A中,返回集合A
}
}
int main()
{
LinkList *LA,*LB;
LinkList *p;
int m;
//输入链表A相关信息
printf("输入链表A的长度:");
scanf("%d",&m);
printf("输入链表A的元素,元素与元素之间用空格间隔开:");
LA=CreateList(m);
//输入链表B相关信息
printf("输入链表LB的长度:");
scanf("%d",&m);
printf("输入链表LB的元素,元素与元素之间用空格间隔开:");
LB=CreateList(m);
//进行两个集合的差集运算
LA=Difference(LA,LB);
p=LA;
printf("\n LA-LB=");
while(p!=NULL)
{
printf("%4d",p->elem );
p=p->next ;
}
return 0;
printf("\n");
}
运行结果