河南大学数据结构实验-顺序表的操作

计算机与信息工程学院实验报告

姓名:杨馥瑞  学号:2212080042 专业:数据科学与大数据技术 

年级:2022

课程:数据结构  主讲教师:袁彩虹老师 辅导教师:_______                 

实验时间:2024年 __月 ___日 __午__时至__时,实验地点_512_

实验题目:顺序表的操作

实验目的:通过该实验,深入理解顺序表的逻辑结构、物理结构等概念,掌握顺序表基本操作的编程实现,注意顺序表插入、删除等操作过程中数据元素的移动现象,培养学生编写程序时,要考虑程序的强壮性,熟练掌握通过函数参数返回函数结果的办法 

实验环境(硬件和软件)Dev c++ & windows11 x64

实验内容:

(1)编程实现顺序表的基本操作:建立顺序表,修改顺序表,插入顺序表,删除顺序表;

(2)采用顺序表结构编程实现:两个集合的运算:交集/并集/差集。

实验步骤:

实验内容(1):

初始化,结构体预定义顺序表

我这里想的是想让它动态扩容就没限制最大大小,所以就没define什么溢出之类的。

                                                                              

顺序表的初始化

感觉c给他指定空间大小就很麻烦,就用c++了

判断是否初始化

求表长

按值查找返回位数

按位查找返回值

顺序表的插入

这里写了个动态扩容,如果长度大于50就*2一下

顺序表的删除

打印顺序表所有元素

销毁顺序表释放空间

实验内容(2):

先初始化并赋值两个集合并检查是否为空,打印出来(附带运行结果)

接着交集的实现

并集的实现

差集的实现

最后销毁释放空间

实验数据记录:

第一个表为集合1的元素,第二个为集合2的元素,第三个为二者的交集,第四个为二者的并集,第五个为集合1与集合2的差集。

问题讨论:

写这个的确遇到了一些问题:

1:关于那个动态扩容,我知道一些STL,它们的动态扩容是很优秀的,比如vector它我记得是动态扩容是根据数据量而看情况的。像比与我只是单纯的*2一下,可能会浪费很多空间数据量大的时候。

2:还有那个我没有在每个顺序表前面加判断是否初始化的操作,单纯因为懒的加了。但是可把我坑惨了,因为我后面,一直调试就是不知道哪里错了,一看忘记初始化了。

3:还有就是那个插入了,感觉没想到一个万全的方法,就把索引为0和1的单拎出来了,然后其它的为一个情况讨论。写这个过程也让我体验到,插入还是链表爽哈哈,直接next指针改一下就行了。

4:接着就是我本身语法的问题了,我本来想着在结构体中初始化data为NULL的结构忘记了这是不合法的了,就在主函数初始化了。

5:还有就是我觉得这么多函数,更适合模块化编程的,但是把函数名一个一个放到.h文件太麻烦了,懒遂罢!

源代码:

#include<iostream>
using namespace std;

#define ElemType int
#define InitSize 50 //初始大小

typedef struct
{
	ElemType *data; //动态分配内存
	int MaxSize,length; //数组的最大容量和当前长度
}SqList;

void InitList(SqList &L)//顺序表的初始化
{
	//L.data = (ElemType *)malloc(MaxSize *sizeof(ElemType)); 这样写很c我选择c艹
	L.data = new ElemType[InitSize];
	L.length = 0;
	L.MaxSize = InitSize;
}
bool Empty(SqList L)//判断是否初始化
{
	if(L.data==NULL)
	{
		printf("顺序表尚未初始化!");
		return false;
	}
	else
		return true;
}
int Length(SqList L)//求表长
{
	return L.length;
}

int LocateElem(SqList L,ElemType e)//按照值查找返回位数
{
	for(int i = 0;i<L.length;i++)
	{
		if(L.data[i]==e)
			return i+1;
	}
	printf("不存在该值!");
	return 0;
	
}

int GetElem(SqList L,int i)//按位查找返回值
{
	
		if(i<1 || i>L.length){
			printf("位数索引有问题!");
			return 0;
		}
		else
			return L.data[i-1];
	
}
void ListInsert(SqList &L,int i,ElemType e)//顺序表的插入
{
	if(i<1 || i>L.length+1)
	{
		printf("插入位置错误!");
	}
		
	if(L.length>=L.MaxSize)// 动态扩容50
	{
        int newMaxSize = L.MaxSize * 2; // 新容量为旧容量的两倍
        ElemType *newData = new ElemType[newMaxSize]; // 创建新数组
        for (int j = 0; j < L.length; j++) {
            newData[j] = L.data[j]; // 复制原有数据到新数组
        }
        delete[] L.data; // 释放旧数组内存
        L.data = newData; // 更新指针
        L.MaxSize = newMaxSize; // 更新容量值
	}
	if (L.length == 0 && i == 1 ) {
    	L.data[i-1] = e;
    	L.length = i;
    
    	return;
		}
	if (L.length == 1 && i == 2) {
    	L.data[i-1] = e;
    	L.length = i;
    	
    	return;
		}
	for(int j = L.length;j>=i;j--)
	{
		L.data[j] = L.data[j-1];
		
	}
	L.data[i-1]=e;
	L.length++;

}

void ListDelete(SqList &L, int i) {//删除元素 
    if (L.length == 0) {
        printf("顺序表为空,无法删除元素!");
        return;
    }
	if (L.length == 1){
		L.length = 0;
	}
    if (i < 1 || i > L.length) {
        printf("删除位置有问题!");
        return;
    }

    for (int j = i; j < L.length; j++) {
        L.data[j - 1] = L.data[j];
    }
    L.length--;
}

void PrintList(SqList L) {//打印所有元素
    printf("顺序表为:\n");
    for (int i = 0; i < L.length; i++) {
        printf("%d ", L.data[i]);
        if ((i + 1) % 10 == 0) {
            printf("\n");
        }
    }
}

void DestroyList(SqList &L) {//销毁操作
    delete[] L.data; // 释放动态分配的数组内存
    L.data = NULL; // 将指针置为NULL,避免悬空指针
    L.length = 0; // 将长度置为0
}
int main()
{
	SqList Set1;//集合 1
	Set1.data= NULL;
	Set1.length=0;

	SqList Set2;//集合 2
	Set2.data= NULL;
	Set2.length=0;

	SqList Result1;//交集
	Result1.data= NULL;
	Result1.length=0;

	SqList Result2;//并集
	Result2.data= NULL;
	Result2.length=0;

	//Set1-Set2 的到的set1为差集结果 

	//假设set1元素为 1 2 3 4 5 6
	//假设set2元素为 6 7 3 1 9 10 123 12
	int arr1[] = {1,2,3,4,5,6};
	int arr2[] = {6,7,3,1,9,10,123,12};

	InitList(Set1);
	InitList(Set2);
	InitList(Result1);
	InitList(Result2);
	if(Empty(Set1)&&Empty(Set2))
		printf("已初始化!");
	else
		printf("未初始化还是空表!");
	for(int i=0;i<6;i++)
	{
		ListInsert(Set1,i+1,arr1[i]);
	}
	for(int i=0;i<8;i++){
		
		ListInsert(Set2,i+1,arr2[i]);
	}
	printf("\n");
	PrintList(Set1);
	printf("\n");
	PrintList(Set2);
	//交集 
	for (int i = 0; i < Set1.length; i++) {
    for (int j = 0; j < Set2.length; j++) {
        if (Set1.data[i] == Set2.data[j]) {
            ListInsert(Result1, Result1.length + 1, Set1.data[i]);
            break;
        }
    }
}
    printf("\n");
	PrintList(Result1);
	
	for (int i = 0; i < Set1.length; i++) {
    ListInsert(Result2, Result2.length + 1, Set1.data[i]);
}
// 遍历第二个集合的元素,插入到结果集合(如果不存在)
for (int i = 0; i < Set2.length; i++) {
    bool exists = false;
    for (int j = 0; j < Result2.length; j++) {
        if (Set2.data[i] == Result2.data[j]) {
            exists = true;
            break;
        }
    }
    if (!exists) {
        ListInsert(Result2, Result2.length + 1, Set2.data[i]);
    }
}
	printf("\n");
	PrintList(Result2);
	
	
// 遍历第一个集合的元素,检查是否存在于第二个集合中
for (int i = 0; i < Set1.length; i++) {
    for(int j = 0;j<Result1.length;j++){
    	if(Set1.data[i]==Result1.data[j])
    	ListDelete(Set1,i+1); 
	}
	}
printf("\n");
PrintList(Set1);
getchar(); 

DestroyList(Set1); 
DestroyList(Set2); 
DestroyList(Result1); 
DestroyList(Result2);
	
}

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值