用单链表实现对集合的交,并,差的操作

    我是一个菜鸟本科生,第一次写博客,排版有些乱,
    主要是想通过博客记录自己的一些学习数据结构的经过与心得感受,
    和正在学习数据结构的小哥哥们一起交流分享。
   用单链表实现集合的判等,交,并,差,基本涉及到了单链表常用的一些操作,
   如建表,插入,删除,遍历,都不算太难。
   首先建表,在建表的过程中,将集合中的元素存入到了链表中,单此时的链表中的元素是无序的,
   在函数Sort_SetList(SET *head)中将链表的头节点作为实参传递到函数的形参中,
   采用冒泡排序的方法交换节点的数据域中的值,实现链表中的元素从小到大的排序。
   在判断两个集合是否相等时,分别将集合所对应的两个链表的头指针传递到判等函数的形参中,
   由于此时集合所对应的单链表时有序的,所以只要同步扫描两个单链表,若从头至尾每个对应的元素都相等,则判等函数返回真,否则返回假。
   在求两个集合的交集时,我开辟了新的内存空间,另建了一个单链表。
#include<stdio.h>
#include<stdlib.h>
#define SET struct set
struct set
{
	int number;
	SET *next;
};
SET *Creat_SetList(char *name);//创建集合的链表
void Print_SetList(SET *head); //输出链表
void Sort_SetList(SET *head);  //集合排序
bool Equal_Set(SET *head_A, SET *head_B);//判断集合是否相等
SET *Intersection_Set(SET *head_A, SET *head_B);//求两个集合的交集
SET *Union_Set(SET *head_A, SET *head_B);  //求两个集合的并集
SET *Difer_Set(SET *head_A, SET *head_B);  //求两个集合的差集
int  main()
{
	int n;
	bool is;
	SET *Set_A, *Set_B,*Set;
	Set_A=Creat_SetList("A");
	Set_B=Creat_SetList("B");
	printf("\n集合A的元素为:");
	Print_SetList(Set_A);
	printf("\n集合B的元素为:");
	Print_SetList(Set_B);
	Sort_SetList(Set_A);
	Sort_SetList(Set_B);
	printf("\n排序之后集合A的元素为:");
	Print_SetList(Set_A);
	printf("\n排序之后集合B的元素为:");
	Print_SetList(Set_B);
	while (true)
	{
		printf("\n1.判断两个集合是否相等\n");
		printf("2.求两个集合的交集\n");
		printf("3.求两个集合的并集\n");
		printf("4.求两个集合的差\n");
		printf("5.退出系统\n");
		scanf_s("%d", &n);
		switch (n)
		{
		case 1: 
			is = Equal_Set(Set_A, Set_B);
			if (is == true)
				printf("两个集合相等\n");
			else
				printf("两个集合不相等\n");
			break;
		case 2:
			Set = Intersection_Set(Set_A, Set_B);
			printf("\n两个集合的交集为:");
			Print_SetList(Set);
			break;
		case 3:
			Set = Union_Set(Set_A, Set_B);
			Sort_SetList(Set);
			printf("\n两个集合的并集为:");
			Print_SetList(Set);
			break;
		case 4:
			Set = Difer_Set(Set_A, Set_B);
			printf("\n两个集合的差集为:");
			Print_SetList(Set);
			break;
		case 5:
			goto exit;
			break;
		default:
			break;
		}
	}
exit:
	return 0;
}
SET *Creat_SetList(char *name)//创建集合的链表
{
	SET *head, *tail, *new_Node;
	head = (SET *)malloc(sizeof(SET));
	new_Node = (SET *)malloc(sizeof(SET));
	printf("请输入集合%s的元素,以-1为结束标志:",name);
	scanf_s("%d", &new_Node->number);
	head->next = new_Node;
	tail = new_Node;
	while (true)
	{
		new_Node = (SET *)malloc(sizeof(SET));
		scanf_s("%d", &new_Node->number);
		if (new_Node->number == -1)
			break;
		tail->next = new_Node;
		tail = new_Node;
	}
	tail->next = NULL;
	return head;
}
void Print_SetList(SET *head) //输出链表
{
	SET *p = head->next;
	while (p != NULL)
	{
		printf("%d  ", p->number);
		p = p->next;
	}
}
void Sort_SetList(SET *head)  //集合从小到大排序
{
	SET *p = head->next;
	SET *end=NULL,*pre=NULL;
	while (p->next != NULL)
	{
		p = p->next;
	}
	end = p;
	while (head->next != end)
	{
		p = head->next;
		while (p != end)
		{
			if (p->number > p->next->number)
			{
				int temp = p->number;
				p->number = p->next->number;
				p->next->number = temp;
			}
			pre = p;
			p = p->next;
		}
		end = pre;
	}
}
bool Equal_Set(SET *head_A, SET *head_B)//判断集合是否相等
{
	SET *pa = head_A->next, *pb = head_B->next;
	while (pa != NULL&&pb != NULL)
	{
		if (pa->number != pb->number)
		{
			return false;
		}
		pa = pa->next;
		pb = pb->next;
	}
	if (pa == NULL&&pb == NULL)
	{
		return true;
	}
	else 
	{
		return false;
	}
}
SET *Intersection_Set(SET *head_A, SET *head_B)//求两个集合的交集
{
	SET *pa = head_A->next, *pb = head_B->next;
	SET *begin = NULL, *end = NULL,*new_Node=NULL;
	begin = (SET *)malloc(sizeof(SET));
	begin->next = NULL;
	while (pa != NULL&&pb != NULL)
	{
		if (pa->number < pb->number)
		{
			pa = pa->next;
		}
		else if(pa->number>pb->number)
		{
			pb = pb->next;
		}
		else
		{
			new_Node= (SET *)malloc(sizeof(SET));
			new_Node->number = pb->number;
			if (begin->next == NULL)
			{
				begin->next = new_Node;
				end = new_Node;
			}
			else
			{
				end->next = new_Node;
				end = new_Node;
				
			}
			pa = pa->next;
			pb = pb->next;
		}
	}
	end->next = NULL;
	return begin;
}
SET *Union_Set(SET *head_A, SET *head_B)  //求两个集合的并集
{
	SET *pa = head_A->next, *pb = head_B->next;
	SET *begin = NULL, *end = NULL, *new_Node;
	begin = (SET *)malloc(sizeof(SET));
	begin->next = NULL;
	while (pa != NULL)
	{
		new_Node = (SET *)malloc(sizeof(SET));
		new_Node->number = pa->number;
		if (begin->next == NULL)
		{
			begin->next = new_Node;
			end = new_Node;
		}
		else 
		{
			end->next = new_Node;
			end = new_Node;
			end->next = NULL;
		}
		pa = pa->next;
	}
	pa = begin->next;
	while (pb != NULL)
	{
		while (pa != NULL)
		{
			if (pb->number == pa->number)
				break;
			pa = pa->next;
		}
		if (pa == NULL)
		{
			pa = begin->next;			
			new_Node = (SET *)malloc(sizeof(SET));
			new_Node->number = pb->number;
			begin->next = new_Node;
			new_Node->next = pa;
		}
		pa = begin->next;
		pb = pb->next;
	}
	return begin;
}
SET *Difer_Set(SET *head_A, SET *head_B)  //求两个集合的差集
{
	SET *pa = head_A->next,*pare=head_A, *pb = head_B->next;
	while (pa != NULL)
	{
		while (pb != NULL)
		{
			if (pa->number == pb->number)
			{
				pare->next = pa->next;
			}			
			pb = pb->next;
		}
		pb = head_B->next;
		pare = pa;
		pa = pa->next;
	}
	return head_A;
}
  • 10
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值