¥1-2 例2.2 将两个集合的并集放到线性表中

该博客介绍了如何使用C++实现线性表操作,特别是两个集合的并集。通过创建和初始化线性表,然后读取元素、插入元素,最后将两个线性表的并集插入到第三个线性表中。样例输入和输出展示了具体的操作过程,代码中包含了线性表的基本操作函数,如初始化、插入、查找等。

将两个集合的并集放到线性表中

题目描述

在这里插入图片描述

样例输入

2
1 3
3
5 3 7

样例输出

1 3 5 7

源代码

#include<iostream>
#include<malloc.h>
using namespace std;
typedef int ElemType;
const int MaxSize = 1000;   //定义最大储存数
class SqList
{
public:
	int data[MaxSize];      //结构体数组
	int length;             // 长度

};
void InitList(SqList*& L)   //初始化线性表
{
	L = (SqList*)malloc(sizeof(SqList));  //分配空间
	L->length = 0;                //使长度为0

}
void CreatList(SqList*& L)   //建立线性表
{
	int n, i, e;
	cin >> n;
	for (i = 0; i < n; i++)
	{
		cin >> e;
		L->data[i] = e;
		L->length++;
	}
}
int ListLength(SqList* L)
{
	return (L->length);
}
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;       //找到返回他的逻辑序号
}
bool GetElem(SqList* L, int i, ElemType& e)
{
	if (i<1 || i>L->length) return false;
	e = L->data[i - 1];
	return true;
}
bool ListInsert(SqList*& L, int i, ElemType e)
{
	int j;
	if (i<1 || i>L->length+1 || L->length == MaxSize)
		return false;
	i--;
	for (j = L->length; j > i; j--)
	{
		L->data[j] = L->data[j - 1];
	}
	L->data[i] = e;
	L->length++;
	return true;
}
void UnionList(SqList * & LA, SqList *&  LB, SqList *& LC)
{
	int i, lena;
	InitList(LC);
	ElemType e;
	
	for (i = 1; i <= ListLength(LA); i++)
	{
		GetElem(LA, i, e);
		ListInsert(LC, i, e);
	}
	lena = ListLength(LA);
	for (i = 1; i <= ListLength(LB); i++)
	{
		GetElem(LB, i, e);
		if (!LocateElem(LA, e))
		{
			ListInsert(LC, ++lena, e);
		}
	}

}

void DispList(SqList* L)
{
	for (int i = 0; i < L->length; i++)
	{
		cout << L->data[i] << " ";

	}
	cout << endl;
}
int main()
{
	SqList* L1, *L2, *L3;
	InitList(L1);
	CreatList(L1);
	InitList(L2);
	CreatList(L2);
	UnionList(L1, L2, L3);
	DispList(L3);
	
	return 0;
}
在数据结构,将两个集合的并集存储到线性 `Lc` ,可以通过以下方式实现: ### 3.1 并集的基本概念 并集指的是两个集合所有元素的组合,且重复元素只保留一次。假设集合 `A` 和集合 `B` 分别对应线性 `La` 和 `Lb`,则集合的并集操作可以理解为:将 `La` 和 `Lb` 的所有元素合并,并去除重复元素后存入线性 `Lc` 。 ### 3.2 线性上的并集操作实现 #### 顺序实现 对于顺序,需要遍历 `La` 和 `Lb` 的所有元素,并逐一检查是否已存在于结果顺序 `Lc` 。如果不存在,则将其插入 `Lc`。 ```c void UnionList(SqList La, SqList Lb, SqList *Lc) { int i; // 初始化 Lc InitList(Lc); // 遍历 La 的所有元素 for (i = 0; i < La.length; i++) { // 如果当前元素不在 Lc ,则插入 if (!LocateElem(Lc, La.data[i])) { ListInsert(Lc, Lc->length + 1, La.data[i]); } } // 遍历 Lb 的所有元素 for (i = 0; i < Lb.length; i++) { // 如果当前元素不在 Lc ,则插入 if (!LocateElem(Lc, Lb.data[i])) { ListInsert(Lc, Lc->length + 1, Lb.data[i]); } } } ``` 其- `InitList()` 用于初始化一个新的顺序- `ListInsert()` 实现了顺序的插入操作。 - `LocateElem()` 检查某个元素是否已经存在于顺序[^3]。 #### 单链实现 对于单链,同样需要遍历两个链的所有节点,并判断目标链是否包含该元素。如果不包含,则将其添加到目标链 `Lc` 。 ```c void UnionLinkList(LinkList La, LinkList Lb, LinkList *Lc) { // 初始化 Lc InitList(Lc); // 遍历 La 所有节点 Node *p = La->next; while (p != NULL) { // 如果当前元素不在 Lc ,则插入 if (!LocateNode(*Lc, p->data)) { ListInsert(Lc, (*Lc)->length + 1, p->data); } p = p->next; } // 遍历 Lb 所有节点 p = Lb->next; while (p != NULL) { // 如果当前元素不在 Lc ,则插入 if (!LocateNode(*Lc, p->data)) { ListInsert(Lc, (*Lc)->length + 1, p->data); } p = p->next; } } ``` 其- `InitList()` 用于初始化一个新的链- `ListInsert()` 实现了链的插入操作。 - `LocateNode()` 检查某个元素是否已经存在于链。 ### 3.3 时间复杂度分析 - **顺序**:时间复杂度主要由遍历和查找决定。假设两个顺序长度分别为 `n` 和 `m`,每次查找的时间复杂度是 $O(n)$,因此总的时间复杂度为 $O(n^2 + m^2)$。 - **链**:与顺序类似,链的查找也需要 $O(n)$ 时间,总时间复杂度也为 $O(n^2 + m^2)$。 为了优化性能,可以使用额外的空间(如哈希)来记录已存在的元素,从而将查找的时间复杂度降低至 $O(1)$,整体时间复杂度可优化为 $O(n + m)$。 ### 3.4 代码示总结 无论是顺序还是链,实现并集的核心逻辑都是遍历两个线性,并确保每个元素仅在结果出现一次。具体实现时,需要注意以下几点: 1. 正确初始化目标线性 `Lc`。 2. 使用查找函数确保不插入重复元素。 3. 对于大容量数据,建议使用更高效的查找机制(如哈希)提升性能。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值