数据结构——算法技能实训【集合运算(C++)】

一个很啰嗦很低级的程序

期末算法技能实训的选题,初学C++和算法,对于时间和空间复杂度的理解不是很深,但写完之后自我感觉这样的代码简直太白痴了,一个简单的集合运算居然写了一千行,不用脑子都能想到这利用率和可用性得多低了,但好歹是自己亲手打出来的,以示警戒,下次不能再整这么啰嗦的算法了。(PS:啰嗦就罗嗦在我想给程序交互界面更人性化点,所以设计了多级菜单以及返回上级菜单的功能),但这样空间代价太大了,不可取。

★写代码时的想法和功能实现基本都在注释里

下面是代码:

#include<iostream>
#include<malloc.h>
using namespace std;

typedef int DataType;
typedef struct Node
{	DataType data;
	struct Node *next;
}ListNode;					// 链表结点 

typedef ListNode *SetLink;

//====================================数据结构定义================================================================ 

SetLink CreatSet();		// 创建集合 
int Set_length(SetLink);		// 集合的长度 
SetLink Search_index_Node(SetLink L,int i);		// 按序号查找 
SetLink Search_value_Node(SetLink L, DataType e);	// 按值查找元素
 DataType insert_Set(SetLink L, int i, DataType e);		// 插入元素 
DataType del_Set(SetLink L, int i);		// 删除元素 
void print_Set(SetLink L);		// 打印集合 


/* 	以上均为单链表的基本操作,查找、删除、插入、求表长等 	*/ 
/*	****************************************************	*/
/*				下面为集合的运算的函数		 				*/


SetLink copy_Set(SetLink L);		// 集合的拷贝 
SetLink add_Set(SetLink A,SetLink B);		// 求集合A,B的并集,将并集赋给集合C 
SetLink common_Set(SetLink A, SetLink B); 		// 求两个集合的交集:将两个集合的公共部分赋值给 C
SetLink sub_Set(SetLink A, SetLink B);				// 这边是求集合A,B的差集
int equal_Set(SetLink A, SetLink B);				// 判断集合 A 和 B 是否相等
SetLink subSet(SetLink A, SetLink B);				// 判断集合A是否为集合B的子集 
void dke_Set(SetLink A, SetLink B);		// 求笛卡尔积 


//	****************************************函数声明完毕,下面是主函数部分【函数定义在687行】 ********************************************* 

 
int main()
{
		int tag,tag1,tag2,tag3,tag4,tag5,tag6,tag7,tag8,tag9,tag10;
		tag=tag1=tag2=tag3=tag4=tag5=tag6=tag7=tag8=tag9=tag10=1;
	do	
	{	
		cout<<"\t================================="<<endl;
		cout<<"\t||				||"<<endl;
		cout<<"\t||	    集合运算		||"<<endl;
		cout<<"\t||				||"<<endl;
		cout<<"\t||				||"<<endl;
		cout<<"\t=================================="<<endl;
		cout<<"\t||				||"<<endl;
		cout<<"\t||	1.创建空集合		||"<<endl;
		cout<<"\t||	2.集合基本操作		||"<<endl;
		cout<<"\t||	3.集合的运算		||"<<endl;
		cout<<"\t||	0.退出			||"<<endl;
		cout<<"\t||				||"<<endl;
		cout<<"\t=================================="<<endl;
		cout<<"请输入你的选项:";
		cin>>tag;
	
		
		switch(tag)
		{
			case 1:
				SetLink A,B;
				A = CreatSet();
				B = CreatSet();
				cout<<"空集合A,B创建完毕"<<"\n"<<endl;
				cout<<"————————————————————————————————————————————————————————————"<<endl;
				cout<<"\n"; 
				break;
			case 2:
				system("cls");
				do
				{
				  
					cout<<"\t================================="<<endl;
					cout<<"\t||				||"<<endl;
					cout<<"\t||	    集合运算		||"<<endl;
					cout<<"\t||				||"<<endl;
					cout<<"\t||				||"<<endl;
					cout<<"\t=================================="<<endl;
					cout<<"\t||				||"<<endl;
					cout<<"\t||	1.插入元素		||"<<endl;
					cout<<"\t||	2.删除元素		||"<<endl;
					cout<<"\t||	3.查询元素		||"<<endl;
					cout<<"\t||	4.输出集合长度		||"<<endl;
					cout<<"\t||	5.输出集合		||"<<endl;
					cout<<"\t||	0.返回上级菜单		||"<<endl;
					cout<<"\t||				||"<<endl;
					cout<<"\t=================================="<<endl;
					cout<<"请输入你的选项:";
					cin>>tag1; 
					
					switch(tag1)
					{
						case 1:
							system("cls");
							do
							{
								cout<<"\t================================="<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||	    集合运算		||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t=================================="<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||	1.对集合A进行插入	||"<<endl;
								cout<<"\t||	2.对集合B进行插入	||"<<endl;
								cout<<"\t||	0.返回上级菜单		||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t=================================="<<endl;
								cout<<"请输入你的选项:";
								cin>>tag2;
								
								switch(tag2)
								{
									case 1:
									{									// 这边涉及到生命期的问题,我在case 2 中也定义了 i,但是C++中变量的生命期以遇到 “} ” 
										int i=1;						// 为终结,所以这边定义的 i 在遇到 switch 的结束 “} ”时生命期才终结,而这时会提示  
										DataType e;						// “[Error] crosses initialization of 'int i' ” 的错误,所以要在case的代码块上加上 “{} ” 
										while(i != 0)					// 以此来终结那些临时变量的生命期 
										{	
											cout<<"\n";
											cout<<"集合A:  请输入插入的位置及元素,以空格分割, 位置及元素均为 0 时退出: ";
											cin>>i>>e;
											if(i==0) { system("cls");	break;} 
											insert_Set(A, i, e); 
										}	// while	
									}	// case 1
									break;
									case 2:
									{
										int i=1;
										DataType e;
										while(i != 0)
										{	
											cout<<"\n";
											cout<<"集合B:  请输入插入的位置及元素,以空格分割, 位置及元素均为 0 时退出: ";
											cin>>i>>e;
											if(i==0) { system("cls");	break;} 
											insert_Set(B, i, e); 
										}	// while
									}	// case 2
									break; 
									case 0:
										break;
									default:
										cout<<"输入错误,请重新输入"<<endl;
										break; 
									
								}	// switch tag2
								
							}while(tag2 != 0);		// do-while
							system("cls");
							break; 		// tag1-case 1 创建空集合 
 
	
						case 2:
							system("cls");
							do
							{
								cout<<"\t================================="<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||	    集合运算		||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t=================================="<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||	1.对集合A进行删除	||"<<endl;
								cout<<"\t||	2.对集合B进行删除	||"<<endl;
								cout<<"\t||	0.返回上级菜单		||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t=================================="<<endl;
								cout<<"请输入你的选项:";
								cin>>tag3;
								
								switch(tag3)
								{
									case 1:
									{
										int i=1;
										while(i != 0)
										{	
											cout<<"\n";
											cout<<"集合A:  请输入删除的位置,当位置为 0 时退出: ";
											cin>>i; 
											if(i==0) { system("cls");	break;} 
											del_Set(A, i); 
										}	//while
									 }	// case 1
									 break;	
									case 2:
									{
										int i=1;
										while(i != 0)
										{	
											cout<<"\n";
											cout<<"集合B:  请输入删除的位置,当位置为 0 时退出: ";
											cin>>i; 
											if(i==0) { system("cls");	break;} 
											del_Set(B, i); 
										}	// while
								     } // case 2
									case 0:
										break;
									default:
										cout<<"输入错误,请重新输入"<<endl;
										break; 
									
								}	// switch tag3	
							}while(tag3 != 0);		// do-while 
							system("cls");
							break;	// tag1-case 2 删除元素 
							
						case 3:
							system("cls");
							do
							{
								cout<<"\t================================="<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||	    集合运算		||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t=================================="<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||	1.对集合A进行查询	||"<<endl;
								cout<<"\t||	2.对集合B进行查询	||"<<endl;
								cout<<"\t||	0.返回上级菜单		||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t=================================="<<endl;
								cout<<"请输入你的选项:";
								cin>>tag4;
								
								switch(tag4)
								{
									case 1:
										system("cls");
										do
										{
											cout<<"\t================================="<<endl;
											cout<<"\t||				||"<<endl;
											cout<<"\t||	    集合运算		||"<<endl;
											cout<<"\t||				||"<<endl;
											cout<<"\t||				||"<<endl;
											cout<<"\t=================================="<<endl;
											cout<<"\t||				||"<<endl;
											cout<<"\t||	1.按序号查找		||"<<endl;
											cout<<"\t||	2.按值查找		||"<<endl;
											cout<<"\t||	0.返回上级菜单		||"<<endl;
											cout<<"\t||				||"<<endl;
											cout<<"\t=================================="<<endl;
											cout<<"请输入你的选项:";
											cin>>tag5;
											
											switch(tag5)
											{
												case 1:
												{
													int i=1;
													while(i != 0)
													{	
														cout<<"\n";
														cout<<"集合A:  请输入查找的位置,当位置为 0 时退出: ";
														cin>>i; 
														if(i==0) { system("cls");	break;} 
														SetLink C;
														C=Search_index_Node(A,i);
														if(C)
														{
															cout<<"集合A 中位置为 "<<i<<"的元素为:"<<C->data<<endl; 
														} 	// if
														else
														{
															cout<<"未查询到该元素,请重新输入"<<endl; 
														}	// if
													}	// while 
												}	// case 1 
												break;	// tag5-case 1 对集合A按序号查询 
												
												case 2:
													DataType e;
													char ch;
													ch = 'a';			// 这边要重置一下 ch 的状态不为q 否则while循环的判断条件(ch != 'q')将失去意义,因为ch赋值完q并退出循环之后并没有改变值,默认还是为'q' 
													do
													{
														cout<<"\n";
														cout<<"集合A:  请输入查找的值,当值为字符 q 时退出: ";
														cin>>e; 
														if(cin.fail()) 
														{ 
															cin.clear();
															system("cls");					// 这边的cin.fail() 方法扣了一天才搞出来 注释纪念一下 
															cin>>ch;
														}
														else			// 这边用了cin的异常捕捉 
														{
														
															if(!Search_value_Node(A,e)) 
															{
																cout<<"未在集合A中查询到值为 "<<e<<"的元素,请重新输入"<<endl; 
																cout<<"\n"<<endl;
															}
														} 	
													}while(ch != 'q');	// while
												break;	// tag5-case 2  对集合A按值查找 
												
												case 0:
													break;
												default:
													cout<<"输入错误,请重新输入"<<endl;
													break; 
												
											}	// switch tag5	
										}while(tag5 != 0);	// do-while
										system("cls");
										break;		// tag4-case 1  对集合A查询 
									
									case 2:
										system("cls");
										do
										{
											cout<<"\t================================="<<endl;
											cout<<"\t||				||"<<endl;
											cout<<"\t||	    集合运算		||"<<endl;
											cout<<"\t||				||"<<endl;
											cout<<"\t||				||"<<endl;
											cout<<"\t=================================="<<endl;
											cout<<"\t||				||"<<endl;
											cout<<"\t||	1.按序号查找		||"<<endl;
											cout<<"\t||	2.按值查找		||"<<endl;
											cout<<"\t||	0.返回上级菜单		||"<<endl;
											cout<<"\t||				||"<<endl;
											cout<<"\t=================================="<<endl;
											cout<<"请输入你的选项:";
											cin>>tag6;
											
											switch(tag6)
											{
												case 1:
												{
													int i=1;
													while(i != 0)
													{	
														cout<<"\n";
														cout<<"集合B:  请输入查找的位置,当位置为 0 时退出: ";
														cin>>i; 
														if(i==0) { system("cls");	break;} 
														SetLink C;
														C=Search_index_Node(B,i);
														if(C)
														{
															cout<<"集合B中位置为 "<<i<<"的元素为:"<<C->data<<endl; 
														} 	// if
														else
														{
															cout<<"未查询到该元素,请重新输入"<<endl;
														} 	// if
													}	// while	
												}	// case 1
												break;	// tag6-case 1  对集合 B 按序号查询 
												
												case 2:
												DataType e;
													char ch;
													ch = 'b';			// 这边要重置一下 ch 的状态不为q 否则while循环的判断条件(ch != 'q')将失去意义,因为ch赋值完q并退出循环之后并没有改变值,默认还是为'q' 
													do
													{
														cout<<"\n";
														cout<<"集合B:  请输入查找的值,当值为字符 q 时退出: ";
														cin>>e; 
														if(cin.fail()) 
														{ 
															cin.clear();
															system("cls");					// 这边的cin.fail() 方法扣了一天才搞出来 注释纪念一下 
															cin>>ch;
														}
														else			// 这边用了cin的异常捕捉 
														{
														
															if(!Search_value_Node(B,e)) 
															{
																cout<<"未在集合B中查询到值为 "<<e<<"的元素,请重新输入"<<endl; 
																cout<<"\n"<<endl;
															}
														} 	
													}while(ch != 'q');	// while
												break;	// tag6-case 2  对集合B按值查找 
												
												case 0:					// 对集合 B 查询的返回上级菜单 
													break;
												default:
													cout<<"输入错误,请重新输入"<<endl;		
													break; 	// 对集合 B 查询的 break 
											
											}	// switch tag6	
										}while(tag6 != 0); 		// do-while
										system("cls");
										break;			// tag4-case 2  对集合 B 进行查询 
										
									case 0:				// tag1-case 3 查询元素  的返回上级菜单 
										break;
									default:
										cout<<"输入错误,请重新输入"<<endl;
										break;
								}	// switch tag4	
							}while(tag4 != 0); 	// do-while
							system("cls");
							break;		// tag1-case 3	查询元素 

						case 4:
							system("cls");
							do
							{
								cout<<"\t================================="<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||	    集合运算		||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t=================================="<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||	1.输出集合A的长度	||"<<endl;
								cout<<"\t||	2.输出集合B的长度	||"<<endl;
								cout<<"\t||	0.返回上级菜单		||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t=================================="<<endl;
								cout<<"请输入你的选项:";
								cin>>tag7;
								
								switch(tag7)
								{
									case 1:
										{
											int count=Set_length(A);
											cout<<"\n"<<endl;
											cout<<"集合A的长度为:"<<count<<endl;
											cout<<"————————————————————————————————————————————————————————————"<<endl;	
										}	// tag7-case 1	集合 A 长度 
										break;	// 集合 A 长度的 break 
										
									case 2:
										{
											int count=Set_length(B);
											cout<<"\n"<<endl;
											cout<<"集合B的长度为:"<<count<<endl;
											cout<<"————————————————————————————————————————————————————————————"<<endl;	
										}// tag7-case 2	集合 B 长度 
										break;	// 集合 B 长度的 break 
											
									case 0:				// tag-case4 输出长度的返回上级菜单 
										break; 
									default:
										cout<<"输入错误,请重新输入"<<endl;
										break; 		
										
								 }	 	
							}while(tag7 != 0);
							system("cls");
							break;		// tag1-case4  输出长度的 break 
							
						case 5:
							system("cls");
							cout<<"\n"<<endl;
							cout<<"集合A"; 
							print_Set(A);
							cout<<"\n"<<"集合B"; 
							print_Set(B);
							cout<<"\n"<<endl;
							cout<<"***********************************************************";
							cout<<"\n"<<endl;
							break;		// tag1-case 5 输出集合的 break 
						
						case 0:			// 集合基本操作的返回上级菜单 
							break;
						default:
							cout<<"输入错误,请重新输入"<<endl;
							break; 
					
					}	// switch tag1   集合基本操作 
				}while(tag1 != 0);	// do while tage1
				system("cls");
				break; 
				
			case 3:
				system("cls");
				do
				{
				  
					cout<<"\t================================="<<endl;
					cout<<"\t||				||"<<endl;
					cout<<"\t||	    集合运算		||"<<endl;
					cout<<"\t||				||"<<endl;
					cout<<"\t||				||"<<endl;
					cout<<"\t=================================="<<endl;
					cout<<"\t||				||"<<endl;
					cout<<"\t||	1.拷贝集合		||"<<endl;
					cout<<"\t||	2.求A和B的并集		||"<<endl;
					cout<<"\t||	3.求A和B的交集		||"<<endl;
					cout<<"\t||	4.求A和B的差集		||"<<endl;
					cout<<"\t||	5.判断A和B是否相等	||"<<endl;
					cout<<"\t||	6.判断子集		||"<<endl;
					cout<<"\t||	7.求集合A和B的笛卡尔积	||"<<endl;
					cout<<"\t||	0.返回上级菜单		||"<<endl;
					cout<<"\t||				||"<<endl;
					cout<<"\t=================================="<<endl;
					cout<<"请输入你的选项:";
					cin>>tag8; 
					
					switch(tag8)
					{
							case 1:
							system("cls");
							do
							{
								cout<<"\t================================="<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||	    集合运算		||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t=================================="<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t||	1.将A拷贝给B		||"<<endl;
								cout<<"\t||	2.将B拷贝给A		||"<<endl;
								cout<<"\t||	0.返回上级菜单		||"<<endl;
								cout<<"\t||				||"<<endl;
								cout<<"\t=================================="<<endl;
								cout<<"请输入你的选项:";
								cin>>tag9;
								
								switch(tag9)
								{
									case 1:
										{
											B=copy_Set(A);
											cout<<"\n"<<endl;
											cout<<"集合A"; 
											print_Set(A);
											cout<<"\n"<<endl;
											cout<<"集合B"; 
											print_Set(B);
											cout<<"\n\n"<<"A已拷贝给B"<<endl;
											cout<<"————————————————————————————————————————————————————————————"<<endl;
										} 	// A 拷贝给 B 
										break;	// A 拷贝给 B 的 break 
										
									case 2:
										{
											A=copy_Set(B);
											cout<<"\n"<<endl;
											cout<<"集合A"; 
											print_Set(A);
											cout<<"\n"<<endl;
											cout<<"集合B";
											print_Set(B);
											cout<<"\n\n"<<"B已拷贝给A"<<endl;
											cout<<"————————————————————————————————————————————————————————————"<<endl;	
										}	// B 拷贝给 A 
										break;	// B 拷贝给 A 的 break 
									case 0:			// tag9 拷贝集合 的返回上级菜单 
										break; 
									default:
										cout<<"输入错误,请重新输入"<<endl;
										break; 
										
								}	// switch tage9  拷贝集合											 	
							}while(tag9 != 0);	// do-while 拷贝集合 
							system("cls");
							break;		// 集合运算 case 1 拷贝集合 的 break  
							 
							case 2:
							{
								SetLink C;	
								C=add_Set(A,B);
								cout<<"并集";
								print_Set(C);
								cout<<"\n"<<endl;
								cout<<"————————————————————————————————————————————————————————————"<<endl;	
							}	// 并集 
							break;	// 并集的 break 
							
							case 3:
							{
								SetLink C;
								C=common_Set(A,B);
								cout<<"交集";
								print_Set(C);
								cout<<"\n"<<endl;
								cout<<"————————————————————————————————————————————————————————————"<<endl;					
							}	// 交集 
							break;	// 交集的 break	
													
							case 4:
							{ 
								SetLink C;
								C=sub_Set(A, B);
								cout<<"差集";
								print_Set(C);
								cout<<"\n"<<endl;
								cout<<"————————————————————————————————————————————————————————————"<<endl;	
							}	// 差集 
							break;	// 差集的 break
							 
							case 5:
							{
								 cout<<(equal_Set(A,B)?"\n集合A和B相等\n\n———————————————————————————————————————————————————————————":\
								 "\n集合A和B不相等\n\n———————————————————————————————————————————————————————————")<<endl; 
							}	// 判断集合相等 
							break;	// 判断集合相等的 break  
							 
							case 6:
								system("cls");
								do
								{
									cout<<"\t================================="<<endl;
									cout<<"\t||				||"<<endl;
									cout<<"\t||	    集合运算		||"<<endl;
									cout<<"\t||				||"<<endl;
									cout<<"\t||				||"<<endl;
									cout<<"\t=================================="<<endl;
									cout<<"\t||				||"<<endl;
									cout<<"\t||	1.判断A是否为B的子集	||"<<endl;
									cout<<"\t||	2.判断B是否为A的子集	||"<<endl;
									cout<<"\t||	0.返回上级菜单		||"<<endl;
									cout<<"\t||				||"<<endl;
									cout<<"\t=================================="<<endl;
									cout<<"请输入你的选项:";
									cin>>tag10; 
									
									switch(tag10)
									{
										case 1:
										{ 
											cout<<(subSet(A,B)?"\n集合A是集合B的子集\n\n———————————————————————————————————————————————————————————":\
											"\n集合A不是集合B的子集\n\n———————————————————————————————————————————————————————————")<<endl; 
										}	// 判断 A 是否为 B 的子集 
										break;	// 判断 A 是否为 B 的子集 的 break 
										 
										case 2:
										{ 
											cout<<(subSet(B,A)?"\n集合B是集合A的子集\n\n———————————————————————————————————————————————————————————":\
											"\n集合B不是集合A的子集\n\n———————————————————————————————————————————————————————————")<<endl; 
										}	// 判断 B 是否为 A 的子集 
										break; 	// 判断 B 是否为 A 的子集 的 break 
										
										case 0:		// 判断子集的返回上级菜单 
											break;
										default:
											cout<<"输入错误,请重新输入"<<endl;
											break; 
									
									}	// switch tag10 判断子集 
								}while(tag10 != 0); 	// do-while 
								system("cls");
								break;		// 判断子集的 break				
							
							case 7:	
								dke_Set(A, B);
								cout<<"\n"<<endl;
								cout<<"————————————————————————————————————————————————————————————"<<endl;
								break;
							
							case 0:					// tag-case 3 集合运算的返回上级菜单 
								break;
							default:
								cout<<"输入错误,请重新输入"<<endl;
								break;	
								
					}	// switch tag8	集合运算的 switch 
				}while(tag8 != 0);		// do-while 
				system("cls");
				break;				// tag-case 3   集合运算的 break 
			
			case 0:				// tag 总菜单的退出 
				break;
			default:
				cout<<"输入错误,请重新输入"<<endl;
				break;	
		}	// switch tag
	}while(tag != 0);	// do-while语句 
 }	// main 
 
 
 
 
 //	****************函数定义***********************************函数定义***************************函数定义************************************ 
 
 SetLink CreatSet()		// 创建集合 
{
	SetLink L;
	L = (SetLink)malloc(sizeof(ListNode));
	if(L) 
	{
		L->next=NULL; return L;
	}
	else 
	{
	cout<<"未分配到空间!"<<endl;
	return 0;  
	}
} 

int Set_length(SetLink L)		// 求链表长度 
{
	SetLink p;			// 工作指针
	p = L->next;
	int count=0;
	while(p)
	{
		count ++;
		p=p->next;
	 } 
	 return count;
}

SetLink Search_index_Node(SetLink L,int i)		// 按序号查找 
{
	SetLink p;
	p=L;
	int j = 0;
	while(p&&j<i)
	{
		j++;
		p=p->next;
	}
	if(!p||j>i)
	{
		return NULL;						// 这里返回空指针 用来在用户交互时if判断 
	} 
	return p;	
}

SetLink Search_value_Node(SetLink L, DataType e)	// 按值查找元素
{
	SetLink p;
	p=L->next;
	int i = 1;
	while(p)
	{	
		if(p->data == e)
		{
			cout<<"查找的值为 "<<e<<" 的元素在第 "<<i<<" 个位置"<<endl;
			return p;
		}
		p=p->next;
		i++;
	}
	return NULL; 
 } 
 
 DataType insert_Set(SetLink L, int i, DataType e)		// 插入元素 
 {
 	SetLink p,q;
 	p=Search_index_Node(L,i-1);
 	if(!p)	return 0;				// 如果未查找到该元素
	q=(SetLink)malloc(sizeof(ListNode));
	q->data = e;
	q->next=p->next;
	p->next=q;
	return 1;
 }
 
DataType del_Set(SetLink L, int i)		// 删除元素 
{
	SetLink p,q;
	p=Search_index_Node(L,i-1);
	q=Search_index_Node(L,i);
	if(p&&q)
	{
		p->next=q->next;
		free(q);
	}
	else	
	return 0;
} 

void print_Set(SetLink L)		// 打印集合 
{
	SetLink p;
	p=L->next;
	if(!p)
	{
		cout<<"该链表为空!"<<endl;	
	}
	
	else
	{
		cout<<"表中元素为:{"; 
		while(p)
		{
			cout<<p->data<<", ";
			p=p->next;	
		}
		cout<<"}";
	}
}

/* 	以上均为单链表的基本操作,查找、删除、插入、求表长等 	*/ 
/*	****************************************************	*/
/*				下面为集合的运算的函数		 				*/

SetLink copy_Set(SetLink L)		// 集合的拷贝 
{
	SetLink L_copy;
	int i=1;
	L_copy=CreatSet();
	SetLink p;
	p=L->next;
	while(p)
	{
		insert_Set(L_copy,i,p->data);
		p=p->next;
		i++;
	}
	
	return L_copy;
}
 
SetLink add_Set(SetLink A,SetLink B)		// 求集合A,B的并集,将并集赋给集合C 
{
	SetLink C;
	C=copy_Set(A);
	int i,flag;
	i=Set_length(C)+1;					// 这边是因为在 tag_insert 处要将B中A没有的元素 
	SetLink p,q;						// 插入到 C 中,而在 insert_Set 函数中,默认是 i-1 
	q=B->next;							// 跳过头结点再查找插入位置的,所以这边需要 +1 处理 
	while(q)
	{
		flag=0;
		p=A->next;
		while(p)							// 此处的 while(p) 是为了寻找 A 中 和 B 中相同 
		{									// 的元素并跳过,用 flag 来表示相同的状态, 
			if(q->data == p->data)			// *1  若有相同的元素则 flag 置为 1,然后 指向 B 中	 
			{								//     元素的指针 q 向后移动,再进行比较。 
				flag = 1;					// *2  若元素不相同,那么 flag 还是开始的 0,则执行 
				break;						// if(flag==0) 的插入语句 
			}
			p=p->next;
		}
		if(flag==0)
		{
			insert_Set(C, i, q->data);			//   上方注释所指的 tag_insert 
			i++;
		}
		q=q->next; 
	}
	return C; 
}

SetLink common_Set(SetLink A, SetLink B) 		// 求两个集合的交集:将两个集合的公共部分赋值给 C
{
	SetLink C;
	C=CreatSet();
	int i,flag;
	i=1;
	SetLink p,q;
	
	q=B->next;
	while(q)
	{
		flag = 0;
		p=A->next;
		while(p)
		{
			if(q->data==p->data)						// 这边用的判断方法和并集的方法大同小异 
			{											// 只是将 flag == 0 插入的判断条件改为 
				flag = 1;								// flag == 1 时执行插入操作 
				break;
			}
			p=p->next;		
		} 
		if(flag==1)
		{
			insert_Set(C, i, q->data);
			i++;		
		}
		q=q->next;	
	}
	return C;		// 这边如果差集为空 那么C->next == NULL,但是判断相等时候不能直接用返回的值做判断 
 } 
 
SetLink sub_Set(SetLink A, SetLink B)				// 这边是求集合A,B的差集,和求并集相比只是少了
{													// 一个拷贝集合 A 到集合 C 的过程
	SetLink C;
	C=CreatSet();
	int i,flag;
	i=1;
	SetLink p,q;
	if(Set_length(A) >= Set_length(B))
	{
		p=A->next;
		while(p)
		{
			flag = 0;
			q=B->next;
			while(q)
			{
				if(q->data==p->data)
				{
					flag=1;
					break;
				}
				q=q->next;
			}
			if(flag==0)
			{
				insert_Set(C, i, p->data);
				i++;
			}
			p=p->next;
		}
		return C;
	}
	else
	{
		p=B->next;
		while(p)
		{
			flag = 0;
			q=A->next;
			while(q)
			{
				if(q->data==p->data)
				{
					flag=1;
					break;
				}
				q=q->next;
			}
			if(flag==0)
			{
				insert_Set(C, i, p->data);
				i++;
			}
			p=p->next;
		}
		return C;
	}
}

int equal_Set(SetLink A, SetLink B)				// 判断集合 A 和 B 是否相等
{
	return((Set_length(A) == Set_length(B)) && (sub_Set(A,B)->next)==NULL);
	
}																			/* 首先判断长度,如果长度不等肯定不相等 
																			 这边因为差集计算的结果是存储在集合 C 中 
																			 所以若两个集合相等,那么他们没有差集元素存在 
																		     则他们返回的集合 C 是 C->next  为 NULL	  */  

SetLink subSet(SetLink A, SetLink B)				// 判断集合A是否为集合B的子集 
{
	SetLink C;
		C=CreatSet();
		int i,flag;
		i=1;
		SetLink p,q;
		if(Set_length(A) <= Set_length(B))
		{
			p=A->next;
			while(p)
			{
				flag = 0;
				q=B->next;
				while(q)
				{
					if(q->data==p->data)
					{
						flag=1;
						break;
					}
					q=q->next;
				}
				if(flag==1)
				{
					insert_Set(C, i, p->data);
					i++;
				}
				p=p->next;
			}
			if(Set_length(A) == Set_length(C))	return C;
			else	return NULL;
		}
		else
		{
			return NULL;
		}						
}

void dke_Set(SetLink A, SetLink B)			// 求笛卡尔积 
{
	SetLink p,q;
	cout<<"集合A和集合B的笛卡尔积为: \n";
	p=A->next;
	while(p)
	{
		q=B->next;
		while(q)
		{
			cout<<p->data<<" "<<q->data<<endl;
			q=q->next; 
		}
		p=p->next;	
	} 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值