一、问题描述
求解一般集合的并集问题。
已知两个集合A和B,现要求一个新的集合A=AUB。
二、问题分析
利用两个线性表LA和LB分别表示集合A和B,只需要扩大线性表LA的集合,将存在于LB而不存在于LA中的数据元素插入到LA中去。只要从LB中依次取得每个数据元素,并依值在LA中进行查找,若不存在,则插入LA中。
三、算法步骤
1.分别获取LA表长m和LB表长n。
2.从LB中第1个数据元素开始,循环n次执行以下操作:
从LB中查找第i个(1<=i<=n)个数据元素赋给e。
在LA中查找元素e,如果不存在,则将e插在表LA的最后。
四、算法描述
完整的代码过程
//******************************线性表的合并******************************//
#include<stdio.h>
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef int Status;
//------顺序表的存储结构------//
#define MAXSIZE 100 //顺序表可能达到的最大长度
typedef struct
{
ElemType *elem; //或ElemType elem[MAXSIZE] 存储空间的基地址
int length; //当前长度
}SqList; //顺序表的结构类型为SqList
//------顺序表的初始化------//
//-----【算法步骤】 -----//
//1.为顺序表L动态分配一个预定义大小的数组空间,使elem指向这段空间的基地址。
//2.将表的当前长度设为0。
bool InitList(SqList &L)
{
//构造一个空的顺序表L
L.elem=new int[MAXSIZE]; //为顺序表分配一个大小为MAXSIZE的数组空间
if(!L.elem) return false; //存储分配失败退出
L.length=0; //空表长度为0
return true;
}
//------顺序表初始化前n个数据------//
bool CreateList(SqList &L,int n)
{
if(n<0||n>MAXSIZE) return false; //n值不合法
for(int i=0; i<n; i++){
scanf("%d",&L.elem[i]);
L.length++;
}
return true;
}
//------顺序表的插入------//
//-----【算法步骤】 -----//
//1.判断插入位置i是否合法(i值的合法范围是1<=i<=n+1),若不合法则返回ERROR。
//2.判断顺序表的存储空间是否已满,若满则返回ERROR。
//3.将第n个至第i个位置的元素依次向后移动一个位置,空出第i个位置(i=n+1时无需移动)。
//4.将要插入的新元素e放入到第i个位置。
//5.表长加1。
Status ListInsert(SqList &L, int i, int e)
{
//在顺序表L中第i个位置插入新的元素e,i值的合法范围是1<=i<=L.length+1
if(i<1||(i>L.length+1)) return ERROR; //i值不合法
if(L.length==MAXSIZE) return ERROR; //当前存储空间已满
for(int j=L.length-1; j>=i-1; j--)
L.elem[j+1]=L.elem[j]; //插入位置及之后的元素后移
L.elem[i-1]=e; //将新元素e放入第i个位置
++L.length; //表长加1
return OK;
}
//------顺序表的查找(按值查找)------//
//-----【算法步骤】 -----//
//1.从第一个元素起,依次和e相比较,若找到与e相等的元素L.elem[i],则查找成功,返回该元素的序号i+1。
//2.若查遍整个顺序表都没有找到,则查找失败,返回0。
int LocateElem(SqList L, int e)
{
//在顺序表L中查找值为e的数据元素,返回其序号。
for(int i=0; i<L.length;i++)
if(L.elem[i]==e) return i+1; //查找成功,返回序号i+1。
return 0; //查找失败,返回0。
}
//------顺序表的查找(按位置查找)------//
//-----【算法步骤】 -----//
//1.判断指定的位置序号i值是否合理(1<=i<=L.length),若不合理,则返回ERROR。
//2.若i值合理,则将第i个数据元素L.length[i-1]赋值给参数e,通过e返回第i个数据元素的传值。
Status GetElem(SqList L, int i, int &e)
{
if(i<1||i>L.length) return ERROR; //判断i值是否合理
e=L.elem[i-1]; //elem[i-1]单元存储第i个数据元素
return OK;
}
//------顺序表的长度------//
int ListLength(SqList L)
{
//直接访问顺序表结构体的当前长度
return L.length; //返回当前表厂
}
//------线性表的合并------//
//-----【算法步骤】 -----//
//1.分别获取LA表长m和LB表长n。
//2.从LB中第1个数据元素开始,循环n次执行以下操作:
//从LB中查找第i个(1<=i<=n)个数据元素赋给e。
//在LA中查找元素e,如果不存在,则将e插在表LA的最后。
void Merage(SqList &LA,SqList LB)
{
//将所有在线性表LB中但不在LA中的数据元素插入到LA中
int e;
int m=ListLength(LA);
int n=ListLength(LB); //求线性表的长度
printf("LA的表长为:%d\n",m);
printf("LB的表长为:%d\n",n);
for(int i=1;i<=n;i++)
{
GetElem(LB,i,e); //取LB中第i个数据元素赋给e
if(!LocateElem(LA,e)) //LA中不存在和e相同的数据元素
ListInsert(LA,++m,e); //将e插在LA最后
}
}
//------输出打印顺序表 按位置从小到大输出顺序表所有元素------//
void PrintList(SqList L)
{
printf("当前顺序表中所有元素为:");
for(int i=0; i<L.length; i++)
{
printf("%d ",L.elem[i]);
}
printf("\n");
}
//------创建顺序表函数------//
void Create_LA(SqList &L)
{
int n;
bool flag;
L.length=0;
printf("请输入要创建的顺序表LA的长度:");
scanf("%d",&n);
printf("请输入依次输入%d个数(空格隔开):",n);
flag=CreateList(L,n);
if(flag){
printf("顺序表LA创建成功!\n");
PrintList(L);
}
else
printf("输入长度不合法!\n");
}
void Create_LB(SqList &L)
{
int n;
bool flag;
L.length=0;
printf("请输入要创建的顺序表LB的长度:");
scanf("%d",&n);
printf("请输入依次输入%d个数(空格隔开):",n);
flag=CreateList(L,n);
if(flag){
printf("顺序表LB创建成功!\n");
PrintList(L);
}
else
printf("输入长度不合法!\n");
}
//------合并线性表函数------//
void MerageList(SqList LA,SqList LB)
{
Merage(LA,LB);
printf("LA和LB合并后的线性表为:");
PrintList(LA);
}
//------创建主函数------//
int main()
{
SqList L,LA,LB;
InitList(LA);
InitList(LB);
Create_LA(LA);
Create_LB(LB);
MerageList(LA,LB);
}
运行结果
请输入要创建的顺序表LA的长度:5
请输入依次输入5个数(空格隔开):1 4 7 2 5
顺序表LA创建成功!
当前顺序表中所有元素为:1 4 7 2 5
请输入要创建的顺序表LB的长度:3
请输入依次输入3个数(空格隔开):3 6 9
顺序表LB创建成功!
当前顺序表中所有元素为:3 6 9
LA的表长为:5
LB的表长为:3
LA和LB合并后的线性表为:当前顺序表中所有元素为:1 4 7 2 5 3 6 9
--------------------------------
Process exited after 10.89 seconds with return value 0
请按任意键继续. . .
五、算法分析
算法的时间复杂度为O(m*n)。