【数据结构】实验三 求两个集合(用单链表表示)的并、交和差运算
    #include<iostream>
using namespace std;
#define ElemType char
typedef struct LNode 
{
	ElemType data; 
	struct LNode* next; 
}LNode, * LinkList; 
void InitList(LinkList& L) 
{
	L = new LNode; 
	L->next = NULL; 
}
void ListInsertLast(LinkList& L) 
{
	LinkList p = L;
	while (p->next != NULL) 
	{
		p = p->next;
	}
	cout << "请输入你要插入的元素(输入0退出):" << endl;
	ElemType x;
	while (1)
	{
		cin >> x;
		if (x == '0') 
			break;
		LNode* s = new LNode; 
		
		s->data = x;
		s->next = NULL;
		p->next = s;
		p = s;
	}
}
void ListInsert(LinkList& L, int i, ElemType e) 
{
	LinkList p = L; 
	int j = 0;
	while (p->next != NULL && (j < i - 1)) 
	{
		p = p->next;
		j++;
	}
	LNode* s = new LNode; 
	s->data = e;
	
	s->next = p->next;
	p->next = s;
}
void OutPutAll(LinkList& L) 
{
	LinkList p = L->next; 
	cout << "中的元素如下:" << endl;
	while (p != NULL) 
	{
		cout << p->data << "\t";
		p = p->next;
	}
	cout << endl;
}
void OutLength(LinkList& L) 
{
	LinkList p = L->next; 
	int i = 0;
	while (p != NULL) 
	{
		i++;
		p = p->next;
	}
	cout << "该链表的长度为:" << i << endl; 
}
void IfNull(LinkList& L) 
{
	if (L->next == NULL)
		cout << "该线性表为空!" << endl;
	else
		cout << "该线性表不为空!" << endl;
}
void OutPut(LinkList& L, int i) 
{
	int j = 0;
	LinkList p = L->next; 
	while (1)
	{
		if (p == NULL) 
		{
			cout << "该线性表长度不够!" << endl;
			return;
		}
		if (j == i - 1) 
		{
			cout << "第" << i << "个元素为:" << p->data << endl;
			return;
		}
		p = p->next;
		j++;
	}
}
void LocateElem(LinkList& L, ElemType e) 
{
	LinkList p = L->next; 
	int i = 1;
	while (p != NULL) 
	{
		if (p->data == e) 
		{
			cout << "元素 " << e << " 在第" << i << "位。" << endl;
			return;
		}
		p = p->next;
		i++;
	}
	cout << "未查到元素" << e << endl; 
}
void Delete(LinkList& L, int i) 
{
	LinkList p = L; 
	int j = 0;
	while (p != NULL) 
	{
		if (j == i - 1) 
		{
			p->next = p->next->next;
			return;
		}
		p = p->next;
		j++;
	}
	cout << "该线性表长度不够!" << endl; 
}
void unSortList(LinkList& L) 
{
	LinkList p1, p2; 
	p1 = L->next;
	L->next = NULL;
	while (p1 != NULL) 
	{
		p2 = p1->next;
		p1->next = L->next;
		L->next = p1;
		p1 = p2;
	}
}
void ShowList() 
{
	cout << "***************************************" << endl;
	cout << "**     --------功能选项--------      **" << endl;
	cout << "**     1.采用尾插法连续插入元素      **" << endl;
	cout << "**     2.输出单链表                  **" << endl;
	cout << "**     3.输出单链表长度              **" << endl;
	cout << "**     4.判断单链表是否为空          **" << endl;
	cout << "**     5.输出单链表的第 i 个元素     **" << endl;
	cout << "**     6.输出某元素的位置            **" << endl;
	cout << "**     7.插入元素                    **" << endl;
	cout << "**     8.删除单链表中的第 i 个元素   **" << endl;
	cout << "**     9.单链表“原地”逆转          **" << endl;
	cout << "**     0.结束程序                    **" << endl;
	cout << "***************************************" << endl;
	cout << "**     --------新增选项--------      **" << endl;
	cout << "**     10.求交集(求交算法)         **" << endl;
	cout << "**     11.求并集(求并算法)         **" << endl;
	cout << "**     12.求差集(集合求差)         **" << endl;
	cout << "***************************************" << endl;
	cout << " >> 请输入您的选项:" << endl;
	cout << " >> ";
}
void Merge_jiao(LinkList& La, LinkList& Lb) 
{
	LinkList pa = La; 
	LinkList pb; 
	LinkList p; 
	while (pa->next != NULL) 
	{
		int t = 1; 
		
		
		pb = Lb->next;
		while (pb != NULL)
		{
			if (pa->next->data == pb->data)
			{
				t = 0; 
				break;
			}
			pb = pb->next;
		}
		if (t == 1)
		{
			p = pa->next;
			pa->next = pa->next->next; 
			delete p;
		}
		else
			pa = pa->next; 
	}
	cout << "集合A与集合B的交集";
	OutPutAll(La); 
}
void Merge_bing(LinkList& La, LinkList& Lb) 
{
	LinkList pa = La; 
	LinkList pb; 
	LinkList p; 
	while (pa->next != NULL) 
	{
		pb = Lb;
		while (pb->next != NULL)
		{
			if (pa->next->data == pb->next->data)
			{
				p = pb->next;
				pb->next = pb->next->next; 
				delete p;
			}
			else
				pb = pb->next;
		}
		pa = pa->next;
	}
	pa->next = Lb->next; 
	cout << "集合A与集合B的并集";
	OutPutAll(La); 
}
void Merge_cha(LinkList& La, LinkList& Lb) 
{
	LinkList pa = La; 
	LinkList pb; 
	LinkList p; 
	while (pa->next != NULL) 
	{
		int t = 1; 
		pb = Lb->next;
		while (pb != NULL)
		{
			if (pa->next->data == pb->data)
			{
				t = 0; 
				break;
			}
			pb = pb->next;
		}
		if (t == 0) 
		{
			p = pa->next;
			pa->next = pa->next->next;
			delete p;
		}
		else 
			pa = pa->next;
	}
	cout << "集合A与集合B的差集";
	OutPutAll(La); 
}
void achieve()
{
	LNode* L; 
	LNode* La, * Lb; 
	
	InitList(L); 
	int i; 
	int select; 
	ElemType e; 
	while (1)
	{
		ShowList();
		cin >> select;
		if (select == 0)
			break;
		switch (select)
		{
		case 1:
			
			ListInsertLast(L);
			cout << "插入后的链表";
			OutPutAll(L);
			break;
		case 2:
			
			OutPutAll(L);
			break;
		case 3:
			
			OutLength(L);
			break;
		case 4:
			
			IfNull(L);
			break;
		case 5:
			
			cout << "请输入i:";
			cin >> i;
			OutPut(L, i);
			break;
		case 6:
			
			cout << "请输入要查找的元素:";
			cin >> e;
			LocateElem(L, e);
			break;
		case 7:
			
			cout << "请输入要插入的位置:";
			cin >> i;
			cout << "请输入要插入的元素:";
			cin >> e;
			ListInsert(L, i, e);
			
			cout << "插入后的链表";
			OutPutAll(L);
			break;
		case 8:
			
			cout << "请输入i:";
			cin >> i;
			Delete(L, i);
			
			cout << "删除后的链表";
			OutPutAll(L);
			break;
		case 9:
			
			unSortList(L);
			cout << "逆序后的链表";
			OutPutAll(L);
			break;
		case 10:
			
			InitList(La); 
			InitList(Lb); 
			cout << "下面为对集合A的操作:" << endl;
			ListInsertLast(La); 
			cout << "下面为对集合B的操作:" << endl;
			ListInsertLast(Lb); 
			Merge_jiao(La, Lb); 
			delete La;
			delete Lb;
			break;
		case 11:
			
			InitList(La); 
			InitList(Lb); 
			cout << "下面为对集合A的操作:" << endl;
			ListInsertLast(La); 
			cout << "下面为对集合B的操作:" << endl;
			ListInsertLast(Lb); 
			Merge_bing(La, Lb); 
			delete La;
			delete Lb;
			break;
		case 12:
			
			InitList(La); 
			InitList(Lb); 
			cout << "下面为对集合A的操作:" << endl;
			ListInsertLast(La); 
			cout << "下面为对集合B的操作:" << endl;
			ListInsertLast(Lb); 
			Merge_cha(La, Lb); 
			delete La;
			delete Lb;
			break;
		default:
			cout << "请输入正确的选项!" << endl;
		}
		system("pause"); 
		system("cls"); 
	}
}
int main()
{
	achieve(); 
	return 0;
}