合肥工业大学 2023级 数据结构 实验一 完整报告
1.实验目标
- 掌握顺序表的基本操作。
- 理解顺序表的存储结构。
- 学会顺序表的算法设计。
2.实验要求
- 顺序表结构和运算定义,算法的实现以库文件方式实现,不得在测试主程序中直接实现;比如存储、算法实现放入文件:seqList.h
- 程序有适当的注释,程序的书写要采用缩进格式。
- 实验程序有较好可读性,各运算和变量的命名直观易懂,符合软件工程要求;
- 程序要具有一定的健壮性,即当输入数据非法时,程序也能适当地做出反应,如插入删除时指定的位置不对等等。
- 程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。
- 程序运行、测试正确;
- 根据实验报告模板详细书写实验报告。
3.实验内容
- 在第i个结点位置插入值为x的结点。
- 删除顺序表中第i个元素结点。
- 在一个递增有序的顺序表L中插入一个值为x的元素,并保持其递增有序特性。
- 将顺序表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的顺序表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。
- 求两个递增有序顺序表L1和L2中的公共元素,放入新的顺序表L3中。
- 删除递增有序顺序表中的重复元素,并统计移动元素次数,要求时间性能最好。
4.数据结构设计(所有存储结构的封装描述)
struct seqList{
int data[MAXLEN];
int listLen;
};
5.算法设计
1、2为书上的基本运算。
3. 在一个递增有序的顺序表L中插入一个值为x的元素,并保持其递增有序特性。
算法设计思想
- 声明一个顺序表L,利用指针传递给形参;
- 先判断顺序表存储空间是否已满;
- 不满时再找到比x大的元素前一个元素下标;
- 插入值为x的元素,顺序表长度加一;
- 输出运行后的顺序表。
算法描述
void zadd(seqList *L,int x){
int i = 0;
if(L->listLen == MAXLEN){
cout << "当前存储空间已满!" << endl;
}
else{
while(L->data[i] < x){ //找到比x大的元素的前一个元素下标
i++;
}
int k = L->listLen;
while(k > i){
L->data[k] = L->data[k-1]; //元素向后移一个位置
k--;
}
L->data[i] = x; //插入元素
L->listLen++; //顺序表长度加一
showList(L);
}
}
4. 将顺序表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的顺序表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。
算法设计思想
- 声明2个顺序表Q,P;
- 利用循环遍历L->data[i]%2是否等于0找到奇数项和偶数项;
- 把奇数项放入Q表中,把偶数项放入P表中;
- 分别输出Q、P表。
算法描述
void part(seqList *L,seqList *Q,seqList *P){
int j = 0,k = 0;
Q->listLen = 0; //建立空表Q
P->listLen = 0; //建立空表P
for(int i = 0;i < L->listLen;i++){
if(L->data[i]%2){ //查找奇数项
Q->listLen++;
Q->data[j] = L->data[i]; //放入Q表中
j++;
}
else{
P->listLen++; //将偶数项放入P表中
P->data[k] = L->data[i];
k++;
}
}
cout << "奇数项"; //输出奇数项
showList(Q);
cout << endl;
cout << "偶数项"; //输出偶数项
showList(P);
cout << endl;
}
5. 求两个递增有序顺序表L1和L2中的公共元素,放入新的顺序表L3中。
算法设计思想
- 声明3个顺序表L,L1,L2,分别用指针传递给L1,L2,L3;
- 利用双重循环找到公共元素;
- 把公共元素放入空表L3中;
算法描述
void pubput(seqList *L1,seqList *L2,seqList *L3){
int k = 0;
L3->listLen = 0; //建立空表L3
for(int i = 0;i < L1->listLen;i++){
for(int j = 0;j < L2->listLen;j++){
if(L1->data[i] == L2->data[j]){ //遍历找到公共元素
L3->listLen++;
L3->data[k] = L1->data[i]; //把公共元素放入L3表中
k++;
}
}
}
if(L3->listLen == 0){ //输出结果
cout << "没有公共元素" << endl;
}
else{
cout << "公共的";
showList(L3);
cout << endl;
}
}
6. 删除递增有序顺序表中的重复元素,并统计移动元素次数,要求时间性能最好。
算法设计思想
- 声明一个顺序表L,利用指针L传递给形参;
- 利用循环找到相同的元素;
- 从相同的第一个元素开始元素前移一个位置,i的下标不变;
- 计算移动次数count。
- 输出删除后的顺序表和移动次数。
算法描述
void delsame(seqList *L){
int count = 0;
for(int i = 0;i < L->listLen-1;i++){
if(L->data[i+1] == L->data[i]){ //找到相同元素
for(int k = i;k < L->listLen-1;k++){
L->data[k] = L->data[k+1]; //元素前移一个位置
}
count += L->listLen-1-i; //计算移动次数
L->listLen--; //顺序表长度减一
i--; //i的下标不变
}
}
cout << "删除后的";
showList(L);
cout << endl;
cout << "移动次数为:" << count << endl;
}
6.运行和测试
1.
第一组数据:顺序表长度n≥10,x=100, i分别为5,n,n+1,0,1,n+2
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
第二组数据:顺序表长度n=0,x=100,i=5
![]() |
2.
第一组数据:顺序表长度n≥10,i分别为5,n,1,n+1,0 (以n=12为例)
![]() | ![]() |
![]() | ![]() |
![]() |
第二组数据:顺序表长度n=0, i=5
![]() |
3. 顺序表元素为 (10,20,30,40,50,60,70,80,90,100),x分别为25,85,110和8
![]() | ![]() |
![]() | ![]() |
4.
第一组数据:顺序表元素为 (1,2,3,4,5,6,7,8,9,10,20,30,40,50,60)
![]() |
第二组数据:顺序表元素为 (10,20,30,40,50,60,70,80,90,100)
![]() |
5.
第一组
第一个顺序表元素为 (1, 3, 6, 10, 15, 16, 17, 18, 19, 20)
第二个顺序表元素为 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 18, 20, 30)
![]() |
第二组
第一个顺序表元素为 (1,3,6,10,15,16,17,18,19,20)
第二个顺序表元素为 (2,4,5,7,8,9,12,22)
![]() |
第三组
第一个顺序表元素为 ()
第二个顺序表元素为 (1,2,3,4,5,6,7,8,9,10)
![]() |
6.
第一组数据:顺序表元素为 (1,2,3,4,5,6,7,8,9)
![]() |
第二组数据:顺序表元素为 (1,1,2,2,2,3,4,5,5,5,6,6,7,7,8,8,9)
![]() |
第三组数据:顺序表元素为 (1,2,3,4,5,5,6,7,8,8,9,9,9,9,9)
![]() |
7.总结、心得和建议
本次实验过程遇到了一个问题,对于指针的用法我还是不够了解,容易搞混弄错,在复习了指针的用法之后才完美解决这次的实验。因为此次实验内容难度较为平和,除了因为一些小错误导致改BUG花费了不少时间,本次实验过程整体比较顺利,希望自己继续努力,仔细、认真完成每一次实验,并在实验过程中发现平时学习的疏漏与不足!
附录(源代码)
seqList.h
#include <iostream>
using namespace std;
#define MAXLEN 100
struct seqList
{
int data[MAXLEN];
int listLen;
};
void showMenu(); //选 择功能函数
void add(seqList *L, int x, int i); //插入函数
void del(seqList *L, int i); //删除函数
void zadd(seqList *L, int x); //递增插入函数
void part(seqList *L, seqList *Q, seqList *P); //奇偶分项函数
void pubput(seqList *L1, seqList *L2, seqList *L3); //公共输出函数
void delsame(seqList *L); //删除重复函数
void showMenu()
{
cout << "1、在第i个结点插入值为x的结点" << endl;
cout << "2、删除顺序表中第i个元素节点" << endl;
cout << "3、递增顺序表插入值为x的元素,且保持递增" << endl;
cout << "4、分离奇偶项" << endl;
cout << "5、两递增顺序表的公共部分" << endl;
cout << "6、删除递增有序的重复元素,移动次数" << endl;
}
void initialList(seqList* L)
{
L->listLen = 0;
}
void createList(seqList* L)
{
int l = 0;
cout << "顺序表长度:";
cin >> l;
int num = 0;
cout << "请输入顺序表元素:" << endl;
for (int i = 0; i < l; i++)
{
cin >> num;
L->data[i] = num;
}
L->listLen += l;
}
void showList(seqList* L)
{
for (int i = 0; i < L->listLen; i++)
{
cout << L->data[i] << " ";
}
cout << endl;
}
//1.在第i个结点位置插入值为x的结点
void add(seqList *L, int x, int i)
{
int j = 0, k = L->listLen;
//第二组数据测试时if条件换成
//if(L->listlen <= 0 i < 1 || i > L->listlen+1)
if (L->listLen < 10 || i < 1 || i > L->listLen + 1) //判断顺序表长度是否满足条件
{
cout << "error" << endl;
}
else if (L->listLen >= MAXLEN)
{
cout << "存储空间已满" << endl;
}
else
{
while (j < i - 1)
{
j++; //找到需要插入结点位置的数组下标
}
while (k > j)
{
L->data[k] = L->data[k - 1]; //所有元素向后移一个位置
k--;
}
L->data[j] = x; //要插入的位置赋值为X
L->listLen++; //顺序表长度加一
showList(L);
}
}
//2.删除顺序表中第i个元素结点。
void del(seqList *L, int i)
{
int j = 0, k = L->listLen;
int m = k;
//第二组数据测试时if条件换成
//if(L->listlen <= 0 || i < 1 || i > L->listlen)
if (L->listLen < 10 || i < 1 || i > L->listLen) //判断顺序表长度是否满足条件
{
cout << "error" << endl;
}
else
{
while (j < i - 1)
{
j++; //找到需要插入结点位置的数组下标
}
while (j < L->listLen - 1)
{
L->data[j] = L->data[j + 1]; //元素向前移一个位置
j++;
}
L->listLen--; //顺序表长度减一
showList(L);
}
}
//3.在递增顺序表中插入值为X的元素,并保持递增。
void zadd(seqList *L, int x)
{
int i = 0;
if (L->listLen == MAXLEN)
{
cout << "当前存储空间已满!" << endl;
}
else
{
while (L->data[i] < x) //找到比x大的元素的前一个元素下标
{
i++;
}
int k = L->listLen;
while (k > i)
{
L->data[k] = L->data[k - 1]; //元素向后移一个位置
k--;
}
L->data[i] = x; //插入元素
L->listLen++; //顺序表长度加一
showList(L);
}
}
//4.分开奇数项和偶数项
void part(seqList *L, seqList *Q, seqList *P)
{
int j = 0, k = 0;
Q->listLen = 0; //建立空表Q
P->listLen = 0; //建立空表P
for (int i = 0; i < L->listLen; i++)
{
if (L->data[i] % 2) //查找奇数项
{
Q->listLen++;
Q->data[j] = L->data[i]; //放入Q表中
j++;
}
else
{
P->listLen++; //将偶数项放入P表中
P->data[k] = L->data[i];
k++;
}
}
cout << "奇数项"; //输出奇数项
showList(Q);
cout << endl;
cout << "偶数项"; //输出偶数项
showList(P);
cout << endl;
}
//5.求两个递增有序顺序表L和L2中的公共元素,放入新的顺序表L3中
void pubput(seqList *L1, seqList *L2, seqList *L3)
{
int k = 0;
L3->listLen = 0; //建立空表L3
for (int i = 0; i < L1->listLen; i++)
{
for (int j = 0; j < L2->listLen; j++)
{
if (L1->data[i] == L2->data[j]) //遍历找到公共元素
{
L3->listLen++;
L3->data[k] = L1->data[i]; //把公共元素放入L3表中
k++;
}
}
}
if (L3->listLen == 0) //输出结果
{
cout << "没有公共元素" << endl;
}
else
{
cout << "公共的";
showList(L3);
cout << endl;
}
}
//6.删除递增有序顺序表中的重复元素,并统计移动元素次数,要求时间性能最好
void delsame(seqList *L)
{
int count = 0;
for (int i = 0; i < L->listLen - 1; i++)
{
if (L->data[i + 1] == L->data[i]) //找到相同元素
{
for (int k = i; k < L->listLen - 1; k++)
{
L->data[k] = L->data[k + 1]; //元素前移一个位置
}
count += L->listLen - 1 - i; //计算移动次数
L->listLen--; //顺序表长度减一
i--; //i的下标不变
}
}
cout << "删除后的";
showList(L);
cout << endl;
cout << "移动次数为:" << count << endl;
}
exp1顺序表实验.cpp
#include <iostream>
using namespace std;
#include "seqList.h"
int main(){
while(true){
showMenu();//显示菜单
seqList L;//定义一个L表
int choice;
cout << "输入你的选择:";
cin >> choice;
int i,x,j,m;
initialList(&L);//初始化链表
createList(&L);//创建链表
switch(choice){
case 1:
cout << "输入插入结点的位置i:";
cin >> i;
cout << "输入插入值x:";
cin >> x;
add(&L,x,i);
break;
case 2:
cout << "输入要删除的结点i:";
cin >> j;
del(&L,j);
break;
case 3:
cout << "输入在递增顺序表中要插入的x的值:";
cin >> m;
zadd(&L,m);
break;
case 4:
seqList A,B;
part(&L,&A,&B);
break;
case 5:
seqList L2,L3;
initialList(&L2);
createList(&L2);
pubput(&L,&L2,&L3);
break;
case 6:
delsame(&L);
break;
default:
cout << "输入错误" << endl;
break;
}
}
system("pause"); //程序结束
return 0;
}

























&spm=1001.2101.3001.5002&articleId=145641369&d=1&t=3&u=348da0f838e641c788d02c4350f0b4a4)
7204

被折叠的 条评论
为什么被折叠?



