集合的并与交验证实验报告

本文详细介绍了如何通过顺序表(线性表)实现集合的并(Union)和交(Intersection)运算,包括伪代码、算法设计、空间和时间复杂度分析,并提供了编译和运行实例。实验结果显示了链表作为数据结构在集合运算中的应用和性能特点。
摘要由CSDN通过智能技术生成

实验题目:验证集合的并与交程序

一、实验目的

  1. 验证集合的并与交程序。

二、实验内容

  1. 有两个顺序表LA和LB,把它们当成集合来使用,考虑它们的并运算和交运算。可以把顺序表当作一个抽象数据类型,直接利用它的定义来实现要求的运算。

三、设计和编码

1. 本实验用到的理论知识

线性表(顺序存储结构)

2. 算法设计

主要展示UnionIntersection两个函数的设计,其余的均是线性表(顺序存储结构)的常见算法。

伪代码如下

void Union(SeqList<T> &LA, SeqList<T> &LB) {
    int n1 = LA.Length(), n2 = LB.Length();
    for (i = 0; i < n2; i++) {
        x = LB.getData(i + 1); //在LB中取一元素
        k = LA.Search(x);      //在LA中搜索它
        if (k == 0)            //若在LA中未找到插入它
        {
            LA.Insert(n1, x);
            n1++;
        } //插入到第n个表项位置}
    }
}
void Intersection(SeqList<T> &LA, SeqList<T> &LB) {
    int n1 = LA.Length();
    for (i = 0; i < n1; i++) {
        x = LA.getData(i + 1); //在LA中取一元素
        k = LB.Search(x); //在LB中搜索它
        if (k == 0) //若在LB中未找到
        {
            LA.Remove(i + 1);
            n1--;
        } //在LA中删除它
        else i++;
    }
}
时间复杂度空间复杂度
O ( n ) O(n) O(n) O ( 1 ) O(1) O(1)

3. 编码

程序清单如下(部分有修改)

// SeqList_main.cpp
// Encoding: UTF-8

#include <iostream> //引入输入输出流
using namespace std;
#include "SeqList.cpp" //引入类SeqList的声明

int main()
{
    int p[5] = {1, 2, 3, 4, 5};
    int q[4] = {0, 4, 5, 6};

    SeqList<int> a(p, 5), b(q, 4);
    cout << "a: ";
    a.PrintList();
    cout << "b: ";
    b.PrintList();
    cout << "Union(a, b): ";
    Union(a, b);
    a.PrintList();

    SeqList<int> c(p, 5), d(q, 4);
    cout << "c: ";
    c.PrintList();
    cout << "d: ";
    d.PrintList();
    cout << "Intersection(c, d): ";
    Intersection(c, d);
    c.PrintList();
}
// SeqList.h
// Encoding: UTF-8

#ifndef SeqList_H //避免重复包含SeqList.h头文件
#define SeqList_H

const int MaxSize = 10; //10只是示例性的数据,可以根据实际问题具体定义

template <typename DataType>
class SeqList
{
public:
    SeqList() { length = 0; }       //无参构造函数,创建一个空表
    SeqList(DataType a[], int n);   //有参构造函数
    ~SeqList() {}                   //析构函数
    void Insert(int i, DataType x); //在线性表第i个位置插入值为x的元素
    DataType Remove(int i);         //删除线性表的第i个元素
    int Search(DataType x);         //求线性表中值为x的元素序号
    void PrintList();               //按序号依次输出各元素
    int Length();                   //求性线表的长度
    int getData(int i);             //按位查找,在线性表中查找第i个元素

    template <typename T>
    friend void Union(SeqList<T> &LA, SeqList<T> &LB); //集合的并

    template <typename T>
    friend void Intersection(SeqList<T> &LA, SeqList<T> &LB); //集合的交

private:
    DataType data[MaxSize]; //存放数据元素的数组
    int length;             //线性表的长度
};
#endif
// SeqList.cpp
// Encoding: UTF-8

#include <iostream> //引入输入输出流
using namespace std;
#include "SeqList.h" //引入类SeqList的声明
                     //以下是类SeqList的成员函数定义
template <typename DataType>
SeqList<DataType>::SeqList(DataType a[], int n)
{
    if (n > MaxSize)
        throw "参数非法";
    for (int i = 0; i < n; i++)
        data[i] = a[i];
    length = n;
}

template <typename DataType>
void SeqList<DataType>::Insert(int i, DataType x)
{
    if (length >= MaxSize)
        throw "上溢";
    if (i < 1 || i > length + 1)
        throw "位置非法";
    for (int j = length; j >= i; j--)
        data[j] = data[j - 1]; //第j个元素存在数组下标为j-1处
    data[i - 1] = x;
    length++;
}

template <typename DataType>
DataType SeqList<DataType>::Remove(int i)
{
    if (length == 0)
        throw "下溢";
    if (i < 1 || i > length)
        throw "位置非法";
    DataType x = data[i - 1];
    for (int j = i; j < length; j++)
        data[j - 1] = data[j]; //此处j已经是元素所在的数组下标
    length--;
    return x;
}

template <typename DataType>
int SeqList<DataType>::Search(DataType x)
{
    for (int i = 0; i < length; i++)
        if (data[i] == x)
            return i + 1; //下标为i的元素其序号为i+1
    return 0;             //退出循环,说明查找失败
}

template <typename DataType>
void SeqList<DataType>::PrintList()
{
    for (int i = 0; i < length; i++)
        cout << data[i] << " ";
    cout << endl;
}

template <typename DataType>
int SeqList<DataType>::Length() { return length; }

template <typename DataType>
int SeqList<DataType>::getData(int i)
{
    if (length == 0)
        throw "下溢";
    if (i < 1 || i > length)
        throw "位置非法";
    return data[i - 1];
}

template <typename T>
void Union(SeqList<T> &LA, SeqList<T> &LB)
{
    int n1 = LA.Length(), n2 = LB.Length();
    int i, k;
    T x;
    for (i = 0; i < n2; i++)
    {
        x = LB.getData(i + 1); //在LB中取一元素
        k = LA.Search(x);      //在LA中搜索它
        if (k == 0)            //若在LA中未找到插入它
        {
            LA.Insert(n1, x);
            n1++;
        } //插入到第n个表项位置}
    }
}

template <typename T>
void Intersection(SeqList<T> &LA, SeqList<T> &LB)
{
    int n1 = LA.Length();
    T x;
    int k, i = 0;
    while (i < n1)
    {
        x = LA.getData(i + 1); //在LA中取一元素
        k = LB.Search(x); //在LB中搜索它
        if (k == 0) //若在LB中未找到
        {
            LA.Remove(i + 1);
            n1--;
        } //在LA中删除它
        else
            i++;
    }
}

四、运行与测试

1. 测试环境

运行环境:Windows 20H2, i7-9750H @ 2.60GHz, 16GB RAM

编译器:gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

编译命令:-g

运行终端:cmd

2. 在调试程序的过程中遇到的问题与解决方案

暂未发现异常。

3. 程序的运行结果

运行结果(符合预期)

D:\OneDrive - mail2.sysu.edu.cn\MyDocuments\code\DSA\week04\集合的并与交>SeqList_main.exe
a: 1 2 3 4 5
b: 0 4 5 6
Union(a, b): 1 2 3 4 0 6 5
c: 1 2 3 4 5
d: 0 4 5 6
Intersection(c, d): 4 5

六、总结与心得

  1. 链表是实现集合的并与交的一种可行的数据结构。但如果想获得更好的性能,可以考虑红黑树,C++ STL 中的 set 就是这么实现的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值