C语言单链表应用之求集合的交并集
本篇文章讲述了如何应用数据结构中的单链表求集合的交并集。思想很简单,建议大家在看这篇博客之前可以先熟悉下用单链表实现两个有序链表的归并。前言
为了方便,本篇文章就以整型数据为例,如果数据是字符型,一定要注意处理空格。一、集合的交并集
比如有两个集合A={1,3,5,7},集合B={3,9}。那么这两个集合的交集是{3},两个集合的并集是{1,3,5,7,9}。
二、算法步骤
1.求并集的函数模块
- 设标志位flag初始值为0。
- 先用循环语句将集合A中的元素复制到并集集合,即单链表C中。
- 再以此判定集合B中的元素是否在集合A中,若存在,置flag=1。
- 当flag=1时,则说明当前B中元素不与A中任何元素相等,将B中此元素用尾插法插入到并集集合C中。
- 集合B中当前元素判断完成后,置标志位flag回到初始值为0,为B中下一个元素判断是否与A中元素相同做准备。
void Union(LinkList L1,LinkList L2,LinkList *L3)
{
LinkList p,q,r,s;
int flag=0;
r=*L3;
//将集合L1都赋值到L3中去
for(p=L1->next;p!=NULL;p=p->next)
{
s=(LinkList)malloc(sizeof(LNode));
s->data=p->data;
r->next=s;
r=s;
s->next=NULL;
}
for(p=L2->next;p!=NULL;p=p->next)
{
for(q=L1->next;q!=NULL;q=q->next)
{
if(p->data==q->data)
{
flag=1;
break;
}
}
if(flag==0)//说明集合B中有集合A中没有的元素,此时尾插法插入到集合A中
{
s=(LinkList)malloc(sizeof(LNode));
s->data=p->data;
r->next=s;
r=s;
}
flag=0;//重置标志位
}
r->next=NULL;
}
2.求交集的函数模块
- 与求并集相类似,利用双重循环,使集合A中一个元素与集合B中所有元素比较,存在相等的元素,用尾插法将该元素插入到交集集合的链表C中,对集合A中所有元素依次重复上述操作,即得到集合A和集合B的交集C。
//reg:标志位,当reg=0时,说明无交集,为1说明有交集
int InterLinkCollection(LinkList L1,LinkList L2,LinkList *L3)
{
LinkList p,q,r,s;
int reg=0;
r=*L3;
for(p=L1->next;p!=NULL;p=p->next)
{
for(q=L2->next;q!=NULL;q=q->next)
{
if(p->data==q->data)
{
s=(LinkList)malloc(sizeof(LNode));
s->data=p->data;
r->next=s;
r=s;
reg=1;
}
}
}
r->next=NULL;
return reg;
}
三、完整代码
/**
* 下面是单链表的应用,集合的交并集
*/
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct LNode
{
char data;
struct LNode *next;
}LNode,*LinkList;
//创建头结点
void InitList(LinkList *L)
{
*L=(LinkList)malloc(sizeof(LNode));
if(!*L)
{
printf("内存分配失败!\n");
exit(0);
}
(*L)->next=NULL;
}
//尾插法创建链表
void CreatList_Tail(LinkList *L)
{
LinkList r,s;
r=*L;
char ch;
scanf("%c",&ch);
while (ch!='$')
{
s=(LinkList)malloc(sizeof(LNode));
s->data=ch;
r->next=s;
r=s;
scanf("%c",&ch);
}
r->next=NULL;
}
void DipList(LinkList L)
{
LinkList p;
p=L->next;
while(p!=NULL)
{
printf("%c ",p->data);
p=p->next;
}
}
//集合的并运算
void Union(LinkList L1,LinkList L2,LinkList *L3)
{
LinkList p,q,r,s;
int flag=0;
r=*L3;
//将集合L1都赋值到L3中去
for(p=L1->next;p!=NULL;p=p->next)
{
s=(LinkList)malloc(sizeof(LNode));
s->data=p->data;
r->next=s;
r=s;
s->next=NULL;
}
for(p=L2->next;p!=NULL;p=p->next)
{
for(q=L1->next;q!=NULL;q=q->next)
{
if(p->data==q->data)
{
flag=1;
break;
}
}
if(flag==0)//说明集合B中有集合A中没有的元素,此时尾插法插入到集合A中
{
s=(LinkList)malloc(sizeof(LNode));
s->data=p->data;
r->next=s;
r=s;
}
flag=0;//重置标志位
}
r->next=NULL;
}
int InterLinkCollection(LinkList L1,LinkList L2,LinkList *L3)
{
LinkList p,q,r,s;
int reg=0;
r=*L3;
for(p=L1->next;p!=NULL;p=p->next)
{
for(q=L2->next;q!=NULL;q=q->next)
{
if(p->data==q->data)
{
s=(LinkList)malloc(sizeof(LNode));
s->data=p->data;
r->next=s;
r=s;
reg=1;
}
}
}
r->next=NULL;
return reg;
}
int main()
{
LinkList L1,L2,L3,L4;
int j;
InitList(&L1);
InitList(&L2);
InitList(&L3);
InitList(&L4);
CreatList_Tail(&L1);
getchar();
CreatList_Tail(&L2);
Union(L1,L2,&L3);
DipList(L3);
printf("\n");
j=InterLinkCollection(L1,L2,&L4);
if(j==0)
printf("无交集\n");
else
DipList(L4);
printf("\n");
return 0;
}