数据结构--c语言链表实现集合的(并,交,补)运算!

数据结构–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)      //当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(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;
	}


	/*
	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(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("请按回车继续!\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");
					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);
					getchar();getchar();system("cls");break;
			default:printf("输入有误!\n"); exit(0);break;
		}
	}
	return 0;
}

最后,相关步骤注意清空,代码中含有一些注释(大佬们若感觉很白痴请自动忽略),另外我所写得代码中的集合A,B的是完全依赖于高中的定义(即三个性质:确定性,互异性,无序性),若代码中存在错误,请评论留言,或者联系qq邮箱:865805295@qq.com,祝大家编程愉快!完!

  • 42
    点赞
  • 244
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
C语言中,我们可以用数组、链表、树等数据结构实现集合。下面,我将用数组和链表来演示集合、并、运算实现过程。 1. 集合的表示 我们可以定义一个结构体来表示集合: ``` typedef struct { int *data; // 指向数据的指针 int size; // 集合的大小 } Set; ``` 2. 集合的创建和销毁 我们可以定义一个函数来创建一个新的集合: ``` Set *createSet(int size) { Set *set = (Set *)malloc(sizeof(Set)); set->data = (int *)malloc(sizeof(int) * size); set->size = size; return set; } ``` 我们也需要定义一个函数来销毁一个集合: ``` void destroySet(Set *set) { free(set->data); free(set); } ``` 3. 集合的插入和删除 我们可以定义一个函数来插入一个元素到集合中: ``` void insert(Set *set, int val) { int i; for (i = 0; i < set->size; i++) { if (set->data[i] == val) { return; } } set->data[set->size++] = val; } ``` 我们也需要定义一个函数来删除一个元素: ``` void remove(Set *set, int val) { int i; for (i = 0; i < set->size; i++) { if (set->data[i] == val) { set->data[i] = set->data[--set->size]; return; } } } ``` 4. 集合的并、和差运算 现在我们已经定义了集合的插入和删除操作,我们可以使用这些操作来实现集合的并、和差运算。 首先,我们来实现集合的并运算集合的并运算可以通过将两个集合中的所有元素合并成一个新的集合实现: ``` Set *unionSet(Set *set1, Set *set2) { Set *set = createSet(set1->size + set2->size); int i; for (i = 0; i < set1->size; i++) { insert(set, set1->data[i]); } for (i = 0; i < set2->size; i++) { insert(set, set2->data[i]); } return set; } ``` 接下来,我们来实现集合运算集合运算可以通过遍历两个集合中的所有元素,找到它们的集来实现: ``` Set *intersect(Set *set1, Set *set2) { Set *set = createSet(set1->size); int i, j; for (i = 0; i < set1->size; i++) { for (j = 0; j < set2->size; j++) { if (set1->data[i] == set2->data[j]) { insert(set, set1->data[i]); break; } } } return set; } ``` 最后,我们来实现集合的差运算集合的差运算可以通过遍历一个集合中的所有元素,找到它们和另一个集合的差集来实现: ``` Set *difference(Set *set1, Set *set2) { Set *set = createSet(set1->size); int i, j; for (i = 0; i < set1->size; i++) { for (j = 0; j < set2->size; j++) { if (set1->data[i] == set2->data[j]) { break; } } if (j == set2->size) { insert(set, set1->data[i]); } } return set; } ``` 到此为止,我们已经实现了用C语言数据结构集合、并、运算

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值