给定两个顺序表(代表两个不同的集合),利用顺序表的基本操作实现这两个集合的并集,交集,差集。
注意:因为集合的元素为字母,所以ElemType为char类型;
如果集合的元素为数字,ElemType要改为int类型。
#include <iostream.h>
#define MaxSize 100
typedef char ElemType;
typedef struct
{
ElemType data[MaxSize];
int length;
} SqList; //定义线性表结构体类型
void InitList(SqList *&L) //引用型指针
{
L= new SqList;
/*分配存放线性表的空间*/
L->length=0;
}
//1.建立一个线性表
void CreateList(SqList *&L,ElemType a[],int n)
{
int i;
for (i=0;i<n;i++)
L->data[i]=a[i];
L->length=n;
}
//2.销毁线性表
void DestroyList(SqList *&L)
{
delete L;
}
//3.判定是否为空表
int ListEmpty(SqList *L)
{
return(L->length==0);
}
//4.求线性表的长度
int ListLength(SqList *L)
{
return(L->length);
}
//5.输出线性表
void DispList(SqList *L)
{
if (ListEmpty(L))
return;
for (int i=0;i<L->length;i++)
cout<<L->data[i]<<" ";
cout<<endl;
}
//6.求某个数据元素值GetElem(L,i,e)
int GetElem(SqList *L,int i,ElemType &e)
{
if (i<1 || i>L->length)
return 0;
e=L->data[i-1];
return 1;
}
//7.按元素值查找
int LocateElem(SqList *L, ElemType e)
{
int i=0;
while (i<L->length && L->data[i]!=e)
i++;
if (i>=L->length)
return 0;
else
return i+1;
}
//8.插入数据元素
int ListInsert(SqList *&L,int i,ElemType e)
{
int j;
if (i<1 || i>L->length+1)
return 0;
i--; /*将顺序表逻辑位序转化为elem下标即物理位序*/
for (j=L->length;j>i;j--)/*将data[i]及后面元素后移一个位置*/
L->data[j]=L->data[j-1];
L->data[i]=e; //将新元素插入该位置
L->length++; /*顺序表长度增1*/
return 1;
}
//9.删除数据元素
int ListDelete(SqList *&L,int i,ElemType &e)
{
int j;
if (i<1 || i>L->length) return 0;
i--; /*将顺序表逻辑位序转化为elem下标即物理位序*/
e=L->data[i];
for (j=i;j<L->length-1;j++) L->data[j]=L->data[j+1];
/*将data[i]之后的元素前移一个位置*/
L->length--; /*顺序表长度减1*/
return 1;
}
将LA的元素全部插入到LC中(也可使用CreateList这个函数),接下来需要筛选 LB 中 LA 没有的元素。
核心理解 if(!LocateElem(LA,e))的意思,即在LA中找不到e(LB的元素)的话,就将e(LB的元素)插入到LC中,相反如果在LA中找得到 e ,就不能将 e 插入到LC中。
注意:区分 ++lena 和 lena++ 的不同
//求两顺序表的并
void unionList(SqList *LA,SqList *LB,SqList *&LC)
{
int lena,i;
ElemType e;
InitList(LC);
for (i=1;i<=ListLength(LA);i++)
/*将LA的所有元素插入到Lc中*/
{
GetElem(LA,i,e);
ListInsert(LC,i,e);
}
lena=ListLength(LA); /*求线性表的长度*/
int lenb=ListLength(LB);
for (i=1;i<=lenb;i++)
{
GetElem(LB,i,e);
/*取LB中第i个数据元素赋给e*/
if (!LocateElem(LA,e))
ListInsert(LC,++lena,e);
/*LA中不存在和e相同者,则插入到LC中*/
}
}
交集
LC为空表,因为LB的长度比LA大,避免会漏缺元素,以LB展开 for 循环。
核心理解 if(LocateElem(LA,e))的意思,即在LA中找到e(LB的元素)的话,就将e(LB的元素)插入到LC中,相反如果在LA中找不到 e ,就不能将 e 插入到LC中。
//求两顺序表的交
void InterList(SqList *LA,SqList *LB,SqList *&LC)
{
int j=0;ElemType e;
for (int i=1;i<=ListLength(LB);i++)
{
GetElem(LB,i,e);
/*取LB中第i个数据元素赋给e*/
if (LocateElem(LA,e))
ListInsert(LC,++j,e);
/*LA中存在和e相同者,则插入到LC中*/
}
}
差集
在差集运算中,两个集合存在共同的元素会相互抵消掉,所以根据这一特性,需要寻找LB中与LA不同的元素。
对于 if(!LocateElem(LA,e))的理解和并集相同。
//求两顺序表的差
void DiffList(SqList *LA,SqList *LB,SqList *&LC)
{
int j=0;ElemType e;
for (int i=1;i<=ListLength(LB);i++)
{
GetElem(LB,i,e);
/*取LB中第i个数据元素赋给e*/
if (!LocateElem(LA,e))
ListInsert(LC,++j,e);
/*LA中存在和e不相同者,则插入到LC中*/
}
}
主函数
对于集合 A-B 和 B-A 只需要L1和L2在差集函数的形参中调换位置就可以了。
void main()
{
SqList *L1;InitList(L1);
ElemType a[4]={'A','B','C','D'};
CreateList(L1,a,4);
cout<<"线性表A的元素为:";DispList(L1);
cout<<endl;
SqList *L2;InitList(L2);
ElemType b[5]={'B','C','E','F','G'};
CreateList(L2,b,5);
cout<<"线性表B的元素为:";DispList(L2);
cout<<endl;
///求并集
SqList *L3;InitList(L3);
unionList(L1,L2,L3);
cout<<"A∪B:";
DispList(L3);
cout<<endl;
///求交集
SqList *L4;InitList(L4);
InterList(L1,L2,L4);
cout<<"A∩B:";
DispList(L4);
cout<<endl;
///求差集
InitList(L4);
DiffList(L2,L1,L4);
cout<<"A-B:";
DispList(L4);
cout<<endl;
///求差集
InitList(L4);
DiffList(L1,L2,L4);
cout<<"B-A:";
DispList(L4);
cout<<endl;
}