数据结构实验报告重邮.docx
《数据结构实验报告重邮.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告重邮.docx(51页珍藏版)》请在冰豆网上搜索。
数据结构实验报告重邮
数据结构实验报告
学院:
班级:
:
学号:
实验一线性链表的实现与操作
题目:
设计一个100位以的长整数加减运算的程序
班级:
:
学号:
完成日期:
一、需求分析
1、本实验中,100位长整数的每位上的数字必须为数字[0——9]之间,长整数的位数并要求100位以。
测试的时候输入数据,当输入回车键的时候结束输入,如果输入的字符不符合题目要求,则程序能过滤这些不符合要求的字符。
2、演示程序以用户和计算机的对话方式执行,即在计算机显示“提示信息”后之后,由用户在键盘上输入演示程序中规定的运算命令;相应的输入数据(滤去输入中不符合要求的字符)和运算结果显示在其后。
3、程序执行的命令包括:
(1)创建第一个整数(100以);
(2)执行加法或者减法;(3)创建第二个整数(100以);(4)结束。
二、概要设计
为实现上述程序功能,可以用链表或者长数组表示长整数,如果用数组表示长整数有个缺点就是长整数不能无限长,而链表能动态开辟空间,它克服了这个缺点,所以次试验用链表来表示长整数。
1、链表的抽象数据类型定义为:
ADTNumber{
数据对象:
D={ai|ai∈(0,1,…,9),i=0,1,2,…,n,n≥0}
数据关系:
R={|ai-1,ai∈D,i=1,2,…,n}
基本操作:
CreateList(&L)
操作结果:
创建一个链表L。
PrintList(L)
初始条件:
链表L已存在。
操作结果:
在屏幕上输出链表的值。
PlusList(L1,L2,a)
初始条件:
链表L1,L2已存在,a为+or–表示加减。
操作结果:
将两链表的值相加然后在屏幕上输出。
DestroyList(&L)
初始条件:
链表L已存在。
操作结果:
销毁链表L。
}ADTNumber
2、本程序包含五个模块:
intmain(){
定义变量;
接受命令;
处理命令;
return0;
}
各模块之间的调用关系如下:
L1L2
+or-:
L2L1
+or-
=
L1L2
三、详细设计
1、定义头文件
#include
#include
#defineLENsizeof(Number)
typedefstructnumberNumber;
structnumber
{
intdata;
Number*next;
Number*prior;
};
///////////////////////////////////////////////////////////////////////////////////////////////////////
voidmain()
{
voidDestoryList(Number*);//释放链表
voidPutNumber(Number*);//将求得的结果输出
Number*GetNumber();//创建链表,放被加数与加数
Number*JiaFa(Number*num_1,Number*num_2);//加法函数
Number*JianFa(Number*num_1,Number*num_2);//减法函数
Number*number_1,*number_2,*number;
charch;//存放运算符号
printf("Enterthefirstlongnumber:
");
number_1=GetNumber();
printf("put+or-:
");
ch=getchar();
fflush(stdin);//吸收不相关的字符
printf("Enterthesecondlongnumber:
");
number_2=GetNumber();
if(ch=='+')
number=JiaFa(number_1,number_2);
else
if(ch=='-')
number=JianFa(number_1,number_2);
printf("\n=\n");
PutNumber(number);
DestoryList(number);
DestoryList(number_1);
DestoryList(number_2);
printf("链表释放完成。
\n");
}
Number*GetNumber()//得到两个链表
{
Number*p,*q,*List;
charch;
p=(Number*)malloc(LEN);
List=p;
List->prior=NULL;
List->data=0;//加法时,放最高位进的1,否者999+1=000
ch=getchar();
while(ch!
='\n')
{
if(ch>='0'&&ch<='9')//过滤非数字字符
{
q=(Number*)malloc(LEN);
q->data=ch-'0';
p->next=q;
q->prior=p;
p=q;
}
ch=getchar();
}
p->next=NULL;
List->prior=NULL;
returnList;
}//加法分两种情况长度相同与不同
Number*JiaFa(Number*num_1,Number*num_2)//返回的数据为逆序
{
Number*p,*q,*r,*s,*num=NULL;
inti=0,j=0;
r=num;
p=num_1;
while(p->next!
=NULL)
{
i++;
p=p->next;
}//i表示number1数字的长度p指向number节点
q=num_2;
while(q->next!
=NULL)
{
j++;
q=q->next;
}//j表示number2数字的长度q指向number节点
s=(Number*)malloc(LEN);
s->prior=NULL;
s->next=NULL;
num=s;
while(i--&&j--)
{
s->data=p->data+q->data;
if(s->data>9)
{
s->data-=10;//**处理两数相加大于9的情况,后面还有
if(i>j)//在长的数据上调整
p->prior->data++;
else
q->prior->data++;
}
r=(Number*)malloc(LEN);
s->next=r;
r->prior=s;
s=r;
p=p->prior;
q=q->prior;
}
r=s=s->prior;//去掉最后一个没数据的节点
free(s->next);
s->next=NULL;
if(i>j)
{
while(i--)
{
if(p->data>9)
{
p->data-=10;//**
p->prior->data++;
}
s=(Number*)malloc(LEN);
s->data=p->data;
p=p->prior;
r->next=s;
s->prior=r;
r=s;
}
if(p->data>0)//**
{
s=(Number*)malloc(LEN);
s->data=p->data;
r->next=s;
s->prior=r;
r=s;
}
}
else
{
while(j--)
{
if(q->data>9)//**
{
q->data-=10;
q->prior->data++;
}
s=(Number*)malloc(LEN);
s->data=q->data;
q=q->prior;
r->next=s;
s->prior=r;
r=s;
}
if(q->data>0)//**
{
s=(Number*)malloc(LEN);
s->data=q->data;
r->next=s;
s->prior=r;
r=s;
}
}
s->next=NULL;//将最后一个next置空
returnnum;
}//减法分3中情况:
被减数长度大于、小于、等于减数长度
Number*JianFa(Number*num_1,Number*num_2)//返回的数据也为逆序
{
Number*p,*q,*r,*s,*num=NULL;
inti=0,j=0;
r=num;
p=num_1;
while(p->next!
=NULL)//i表示number1数字的长度p指向number节点
{
i++;
p=p->next;
}
q=num_2;
while(q->next!
=NULL)//j表示number2数字的长度q指向number节点
{
j++;
q=q->next;
}
s=(Number*)malloc(LEN);
s->prior=NULL;
s->next=NULL;
num=s;
if(i{
while(i--)
{
s->data=q->data-p->data;
if(s->data<0)//**
{
s->data+=10;
q->prior->data--;
}
r=(Number*)malloc(LEN);
s->next=r;
r->prior=s;
s=r;
p=p->prior;
q=q->prior;
j--;//使i,j同时变化
}
r=s=s->prior;//去掉最后一个没数据的节点
free(s->next);
s->next=NULL;
while(j--)
{
if(q->data<0)//**
{
q->data+=10;
q->prior->data--;
}
s=(Number*)malloc(LEN);
s->data=q->data;
q=q->prior;
r->next=s;
s->prior=r;
r=s;
}
s->data=0-s->data;//反号,因为节点里不能放符号,而直接在最高位前加负号最简单
s->next=NULL;
}
else
if(i==j)
{
i=j=1;
p=num_1;q=num_2;
while(p->data==q->data)
{
p=p->next;
q=q->next;
}
num_1=(Number*)malloc(LEN);
num_1->prior=NULL;
num_1->data=0;
num_1->next=p;
num_2=(Number*)malloc(LEN);
num_2->prior=NULL;
num_2->data=0;
num_2->next=q;
while(p->next!
=NULL)//i表示number1数字的长度p指向number节点
{
i++;
p=p->next;
}
q=num_2;
while(q->next!
=NULL)//j表示number2数字的长度q指向number节点
{
j++;
q=q->next;
}
if(num_1->next->data>num_2->next->data)
{
while(i--)
{
s->data=p->data-q->data;
if(s->data<0)//**
{
s->data+=10;
p->prior->data--;
}
r=(Number*)malloc(LEN);
s->next=r;
r->prior=s;
s=r;
p=p->prior;
q=q->prior;
}
r=s=s->prior;//去掉最后一个没数据的节点
free(s->next);
while(s->data==0&&s->prior!
=NULL)//去掉前面多余的0,否则111112-111111=000001
{
s=s->prior;
free(s->next);
}
}
if(num_1->next->datanext->data)
{
while(i--)
{
s->data=q->data-p->data;
if(s->data<0)//**
{
s->data+=10;
q->prior->data--;
}
r=(Number*)malloc(LEN);
s->next=r;
r->prior=s;
s=r;
p=p->prior;
q=q->prior;
}
r=s=s->prior;//去掉最后一个没数据的节点
free(s->next);
while(s->data==0&&s->prior!
=NULL)//去掉前面多余的0,否则111112-111111=000001
{
s=s->prior;
free(s->next);
}
}
s->data=0-s->data;//反号,因为节点里不能放符号,而直接在最高位前加负号最简单
s->next=NULL;
}
else
if(i>j)
{
while(j--)
{
s->data=p->data-q->data;
if(s->data<0)//**
{
s->data+=10;
p->prior->data--;
}
r=(Number*)malloc(LEN);
s->next=r;
r->prior=s;
s=r;
p=p->prior;
q=q->prior;
i--;
}
r=s=s->prior;//去掉最后一个没数据的节点
free(s->next);
s->next=NULL;
while(i--)
{
if(p->data<0)//**
{
p->data+=10;
p->prior->data--;
}
s=(Number*)malloc(LEN);
s->data=p->data;
p=p->prior;
r->next=s;
s->prior=r;
r=s;
}
while(s->data==0&&s->prior!
=NULL)//去掉前面多余的0,否则1000-1=0999
{
s=s->prior;
free(s->next);
}
//s->data=0-s->data;//反号,因为节点里不能放符号,而直接在最高位前加负号最简单
s->next=NULL;
}
returnnum;
}
voidPutNumber(Number*num)//链表的合并
{
Number*p;
intk=1,i;//k为数据长度,i控制‘,’
p=num;
while(p->next!
=NULL)
{
p=p->next;
k++;
}
i=4-k%4;
while(k--)
{
i++;
printf("%d",p->data);
p=p->prior;
if(k!
=0&&i%4==0)//长度为k的数据,在k%4个数字后开始输出‘,’数据输出完后不输出‘,’
putchar(',');
}
putchar('\n');
}
voidDestoryList(Number*list)//销毁链表
{
Number*p,*q;
p=list;
while(p)
{
q=p->next;
free(p);
p=q;
}
}
四、调试分析
1、这个程序是看了原模版的分析才了解到具体是怎样去存储长整数。
进位的部分很纠结,不知道用什么去移动,然后才知道直接用指针去操作就好了。
2、本程序有些代码重复出现,影响了代码的编译效率。
3、本程序模块划分比较合理,且把指针全部封装在链表模块中,操作方便。
五.运行结果
六、实验环境
(1)Win8系统,兼容
(2)编程环境:
VC6.0++简体中文版
七、实验体会
通过此次实验,我理解了线性链表的逻辑结构和链式存储结构并一定程度的掌握了线性链表的基本操作及应用。
这是一个培养学生灵活使用结构解决实际问题的能力。
开始想的是要用数组去存储长整数,但是看过实验报告的模版后,了解到原来还可以用链表来存如此大的长整数。
这个思路很大的启发了我。
觉得以后编程时也是可以运用的一种重要思想。
而且我了解到,在编写程序的时候养成良好编程风格很重要,这样可以使以后自己或者他人阅读这个程序的难度大大降低。
实验二栈和队列的应用
题目:
利用队列宽度优先进行迷宫求解
班级:
:
学号:
完成日期:
一、需求分析
1.本实验中,要求用数组表示迷宫,并建立队列,利用队列实现宽度优先搜索。
从而得到迷宫的解。
2.队列是顺序存储结构,其存储结构示意图如下:
3、程序执行的命令包括:
(1)输出迷宫,并介绍迷宫规则;
(2)输入测试数据;(3)输出迷宫解答方案;
4、测试数据
Pleaseinputthestartpoint:
00
Wrongstartpoint,pleaseinputagain:
23
Output:
图示;
2、算法概要设计
1.建立如下函数,抽象数据类型定义为:
ADTsqllist{
voidEnterQ(inti,intj,intk);定义一个入队的函数
voidDelectQ(int*i,int*j,int*k);获取当前结点的序号和对应的迷宫坐标,然后出列,返回函数值;
boolGetNextPos(int*i,int*j,intcount);布尔值,得到下一个邻接点的位置。
voidShortestPath_BFS(inti,intj);利用广度优先遍历寻找最短路径的函数;
voidShortestPath();输出最短路径
}
2.
函数声明;
voidmain(){
初始化;
建立变量;
调用函数;
}
本程序分为以下三个模块:
变量声明模块
调用
构建函数模块
调用
主程序模块;
三、详细设计
#include
voidEnterQ(inti,intj,intk);//定义一个入队的函数
voidDelectQ(int*i,int*j,int*k);//出列函数,获取当前结点的序号和对应的迷宫坐标,然后出列,返回函数值
boolGetNextPos(int*i,int*j,intcount);//布尔值,得到下一个邻接点的位置。
voidShortestPath_BFS(inti,intj);//利用广度优先遍历寻找最短路径的函数
voidShortestPath();//输出最短路径
voidPrint();
intMap[10][10]={{1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,1,0,0,0,1,0,1},
{1,0,0,0,0,1,1,0,0,1},
{1,0,1,1,1,0,0,0,0,1},
{1,0,0,0,1,0,0,0,0,1},
{1,0,1,0,0,0,1,0,0,1},
{1,0,1,1,1,0,1,1,0,1},
{1,1,0,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1,1,1}};
structNode
{
intparent_id;//保存父结点的位置
intnode_id;//当前结点的序号
intx,y;//当前结点对应的坐标
}Q[10*10];
intfront=0,rear=0;//队列头指针和尾指针
voidmain()
{
cout<<"progammingintroduce:
"<<'\n'<<"1.outputtheshortestpath;"<<'\n'<<"2.theexitis