一个很啰嗦很低级的程序
期末算法技能实训的选题,初学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;
}
}