链表求交集、并集和差集
C语言建立链表,输入集合A和集合B,求集合A和B的交集、并集和差集;
求交集写了两种,一种是求两个非递减集合的交集,另一种是无序集合
以下是打代码块
#include <stdio.h>
#include <stdlib.h>
int ans;
typedef struct Lnode{
int data;
struct Lnode *next;
}Lnode,*LinkList;
//链表初始化
LinkList InitList(LinkList L,int n){
int data;
L = (LinkList)malloc(sizeof(Lnode));
//建立头结点
L->next = NULL;
//定义一个head指向L的头部
LinkList head = L;
for(int i = 0;i < n;i++){
LinkList p = (LinkList)malloc(sizeof(Lnode));
scanf("%d",&data);
p->data = data;
p->next = L->next;
L->next = p;
L=L->next;
}
return head;
}
//插入数据
LinkList InsertList(LinkList L,int i,int data){
LinkList head = L;
//标记插入的位置
int mark = 1;
while(L){
if(mark == i){
LinkList p = (LinkList)malloc(sizeof(Lnode));
p->data = data;
p->next = L->next;
L->next = p;
free(p);
break;
}
mark++;
L = L->next;
}
return head;
}
//求交集(有序)
LinkList Intersection(LinkList L1,LinkList L2){
//存放交集C
LinkList L3 = (LinkList)malloc(sizeof(Lnode));
//初始化一下;
L3->next = NULL;
//标记C集合的头结点;
LinkList head = L3;
//用来替换L1,L2;
LinkList p = L1->next,q= L2->next;
//如果一个为空,跳出循环;
while(p&&q){
//如果相等,存入集合C
if(p->data == q->data){
LinkList tmp = (LinkList)malloc(sizeof(Lnode));
tmp ->data = p->data;
tmp->next = L3->next;
L3->next = tmp;
L3 = L3->next;
p = p->next;
q = q->next;
continue;
}
//链表是递增顺序,如果集合A的数值小于集合B的数值,集合A往后移动一位,
if(p->data > q->data){
q = q->next;
}
//反之,移动集合B
if(p->data < q->data){
p = p->next;
}
}
//返回标记的头;
return head;
}
//查找数值
int Searchvalue(LinkList L,int data){
LinkList head = L->next;
while(head){
if(head->data == data){
return 1;
}
head = head->next;
}
return 0;
}
//删除链表的值
LinkList DeleteList(LinkList L,int data){
LinkList head = L;
while(L){
if(L->next!=NULL&&L->next->data == data){
L->next = L->next->next;
break;
}
L = L->next;
}
return head;
}
//求交集(无序集合)
LinkList Intersection01(LinkList L1,LinkList L2){
LinkList q = L1, p = L2;
LinkList L = (LinkList)malloc(sizeof(Lnode));
L ->next = NULL;
LinkList head = L;
while(q){
if(Searchvalue(L2,q->data)){
LinkList tmp = (LinkList)malloc(sizeof(Lnode));
tmp ->data = q->data;
tmp->next = L->next;
L->next = tmp;
L = L->next;
}
q = q->next;
}
return head;
}
//求差集(直接对L1进行操作)
void differentSet(LinkList L1,LinkList L2){
//指向L1,L2
LinkList p = L1->next,q = L2->next;
//循环L2;
while(q){
//在L1中查找L2的值,如果相等,就在L1中删除该值
if(Searchvalue(L1,q->data)){
L1 = DeleteList(L1,q->data);
}
q = q->next;
}
}
//求差集(零件一个链表储存)
LinkList differentSet01(LinkList L1,LinkList L2){
//建立集合C储存差集
LinkList L = (LinkList)malloc (sizeof(Lnode));
L ->next = NULL;
LinkList head = L;
//替换L1,L2,防止两个链表被破坏
LinkList p = L1->next,q = L2->next;
//循环L2;
while(p){
//在L1中查找L2的值,如果相等,就在L1中删除该值
if(!Searchvalue(L2,p->data)){
LinkList tmp = (LinkList)malloc(sizeof(Lnode));
tmp ->data = p->data;
tmp->next = L->next;
L->next = tmp;
L = L->next;
}
p = p->next;
}
return head;
}
//求并集
LinkList Unionset(LinkList L1,LinkList L2){
//替换L1,L2;
LinkList p = L1->next,q = L2->next;
//集合C存并集
LinkList uni = (LinkList)malloc(sizeof(Lnode));
uni->next = NULL;
LinkList head_un = uni;
ans = ans+1;
while(p){
LinkList tmp = (LinkList)malloc(sizeof(Lnode));
tmp->data = p->data;
tmp->next = uni->next;
uni->next = tmp;
p = p->next;
uni = uni->next;
}
while(q){
if(!Searchvalue(L1,q->data)){
InsertList(head_un,ans,q->data);
ans ++;
}
q = q->next;
}
return head_un;
}
//输出链表
void printList(LinkList L){
LinkList head = L->next;
while(head){
printf("%d ",head->data);
head=head->next;
}
printf("\n");
}
int main()
{
LinkList L1,L2;
int n;
scanf("%d",&n);
ans = n;
L1 = InitList(L1,n);
scanf("%d",&n);
L2 = InitList(L2,n);
printf("输出交集:");
printList(Intersection01(L1,L2));//输出交集
//differentSet(L1,L2);//求差集,不开空间存储
//L1 = DeleteList(L1,5);//测试删除功能;
LinkList L = differentSet01(L1,L2);//求差集
printf("输出差集:");
printList(L);//输出差集
printf("输出并集:");
//输出并集
printList(Unionset(L1,L2));
return 0;
}