线性表的合并

一、问题描述

        求解一般集合的并集问题。

        已知两个集合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)。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是将两个线性表合并C语言完整代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 // 定义线性表最大长度 typedef struct { int data[MAX_SIZE]; // 存储数据元素 int length; // 线性表当前长度 } List; void initList(List *l) { l->length = 0; // 初始化线性表长度为0 } void insertList(List *l, int index, int value) { if (index < 1 || index > l->length + 1) { // 判断插入位置是否合法 printf("插入位置不合法!\n"); return; } if (l->length == MAX_SIZE) { // 判断线性表是否已满 printf("线性表已满,无法插入!\n"); return; } for (int i = l->length; i >= index; i--) { // 从后向前依次将元素后移 l->data[i] = l->data[i - 1]; } l->data[index - 1] = value; // 将新元素插入到指定位置 l->length++; // 线性表长度加1 } void mergeList(List *l1, List *l2, List *l3) { int i = 0, j = 0, k = 0; while (i < l1->length && j < l2->length) { // 依次比较两个线性表中的元素 if (l1->data[i] <= l2->data[j]) { l3->data[k] = l1->data[i]; i++; k++; } else { l3->data[k] = l2->data[j]; j++; k++; } } while (i < l1->length) { // 将剩余元素插入到合并后的线性表中 l3->data[k] = l1->data[i]; i++; k++; } while (j < l2->length) { // 将剩余元素插入到合并后的线性表中 l3->data[k] = l2->data[j]; j++; k++; } l3->length = k; // 设置合并后的线性表长度 } int main() { List l1, l2, l3; initList(&l1); initList(&l2); initList(&l3); insertList(&l1, 1, 1); insertList(&l1, 2, 3); insertList(&l1, 3, 5); insertList(&l2, 1, 2); insertList(&l2, 2, 4); insertList(&l2, 3, 6); mergeList(&l1, &l2, &l3); printf("合并后的线性表:\n"); for (int i = 0; i < l3.length; i++) { // 遍历输出合并后的线性表 printf("%d ", l3.data[i]); } printf("\n"); return 0; } ``` 在这个例子中,我们定义了一个 `List` 结构体表示线性表,其中 `data` 数组存储数据元素,`length` 表示当前线性表长度。我们定义了 `initList` 函数用于初始化线性表,`insertList` 函数用于插入元素,`mergeList` 函数用于合并两个线性表。在 `main` 函数中,我们创建两个线性表 `l1` 和 `l2`,并将它们合并到 `l3` 中,最后输出合并后的线性表

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值