计算机与信息工程学院实验报告
姓名:杨馥瑞 学号: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);
}