如何用C语言实现单链表的集合运算(头插法)

#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数据显示\n");
printf("\t\t\t4 集合B数据显示\n");
printf("\t\t\t5 集合A和集合B的并集\n");
printf("\t\t\t6 集合A和集合B的交集\n");
printf("\t\t\t7 集合A和集合B的差集\n");
printf("\t\t\t0 退出系统\n");
printf("\n");
printf("\t\t*********单链表(头插法)集合运算*************\n");
printf("\n");

}
// 输入
Status input(LinkList &L,int n) //不能写成input(LinkList L,int n),这样的值不会改变
{
LinkList p;
int i;
for(i = 1;i <= n;i ++)
{
printf(“请输入集合的第%d个数:”,i);
p=(LinkList)malloc(sizeof(LNode));
if(p!=NULL)
{
scanf("%d",&p->data);
p->next = L->next; //头插法
L->next = p;
}
else
return ERROR;
}
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指向的链表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 and_set(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的最后为空时就可以将A中的一个元素插入C中
	{
		s=(LinkList)malloc(sizeof(LNode));  //s指针用来控制C中的数据
		s->data=p->data;  //头插法
		s->next=Lc->next;
		Lc->next=s;
	}
	p=p->next;
}

/*
//插A
while(p!=NULL)
{
	q=Lc->next;  //指针q控制扫描链表Lc的每一个结点(元素)
	while(q && (q->data != p->data))
		q=q->next;
	if(!q) //La中没找到与Lc链表中相同的结点时,就把La上结点在Lc上插入(把集合La的元素填入集合Lc)
	{
		s=(LinkList)malloc(sizeof(LNode));
		s->data=p->data;
		s->next=Lc->next;   //插入到头部
		Lc->next=s;
	}
	p=p->next;  //指向下一个结点
}
p=Lb->next;
*/
//插B
/*while(p!=NULL)
{
	q=Lc->next;
	while(q && (q->data != p->data))  //如果找到Lb中的元素与Lc中的元素相同则就继续循环否则就结束循环
		q=q->next;
	if(!q) //满足没找到相同元素的情况
	{
		s=(LinkList)malloc(sizeof(LNode)); //创建一个新的结点
		s->data=p->data;    //将Lb中的元素赋给s结点
		s->next=Lc->next;  //然后插入到Lc表的头部
		Lc->next=s;
	}
	p=p->next;
}*/

}

//交集 (先清空C链表,再A与B中找相同的break(不为空,记录),再与C中比较(与并集同理插入)插入C中即可)
void intersection(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§ //A中不为空时
{
q=Lb->next;
while(q)
{
if(p->dataq->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;
}

/*
p=La->next;
while(p)
{
	q=Lb->next;
	while(q)
	{
		if(q->data==p->data)  
			break;
		else
			q=q->next;
	}
	if(q)
	{
		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;
}*/

}

//差集 (先清空C后,找A中与B中不同的,找到B最后,即NULL的时候插入即可!)
void difference_set(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(qNULL)
{
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("请按回车继续!\n");
			    getchar();getchar();system("cls");break;
		case 2:ClearList_L(Lb);printf("请输入集合B要插入的个数:\n");scanf("%d",&y);input(Lb,y);
				printf("请按回车继续!\n");
				getchar();getchar();system("cls");break;
		case 3:printf("集合A为:\n");
				Output(La);
				printf("请按回车继续!\n");
				getchar();getchar();system("cls");break;
		case 4:printf("集合B为:\n");
				Output(Lb);
				printf("请按回车继续!\n");
				getchar();getchar();system("cls");break;
		case 5:printf("集合A与集合B的并集为:\n");
				and_set(La,Lb,Lc);
				Output(Lc);
				printf("请按回车继续!\n");
				getchar();getchar();system("cls");break;
		case 6:printf("集合A与集合B的交集为:\n");
				getchar();getchar();system("cls");break;
		default:printf("输入有误!\n"); exit(0);break;
	}
}
return 0;
				intersection(La,Lb,Lc);
				Output(Lc);
				printf("请按回车继续!\n");
				getchar();getchar();system("cls");break;
		case 7:printf("集合A与集合B的并集为:\n");
				difference_set(La,Lb,Lc);
				Output(Lc);
				printf("请按回车继续!\n");
				getchar();getchar();system("cls");break;
		case 0:printf("成功退出系统!\n");exit(0);

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉默着忍受

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值