南京航空航天大学数据结构软件技术上机报告分解.docx
《南京航空航天大学数据结构软件技术上机报告分解.docx》由会员分享,可在线阅读,更多相关《南京航空航天大学数据结构软件技术上机报告分解.docx(33页珍藏版)》请在冰豆网上搜索。
![南京航空航天大学数据结构软件技术上机报告分解.docx](https://file1.bdocx.com/fileroot1/2022-12/16/4fda7622-9d03-4684-a956-74b66e82fd37/4fda7622-9d03-4684-a956-74b66e82fd371.gif)
南京航空航天大学数据结构软件技术上机报告分解
《计算机软件技术基础》
实验报告I—数据结构
班号:
0312401学号:
031240117
姓名:
尚林伟Email:
235445892@
签名:
尚林伟
南京航空航天大学
2014年11月5日
目录
实验一:
顺序表、单链表的定义、创建、插入和删除操作,将数据元素显示出来。
P1~5
实验二:
二叉树的链式存储结构的数据结构定义、创建、先序/中序/后序遍历,并将结果序列输出。
P5~6
实验三:
图的邻接表和邻接矩阵数据结构的定义、创建;图的深度优先遍历、广度优先遍历。
P6~12
实验总结:
P13
一、实验要求
●简述每一部分的对象、目的和要求;
●画出算法(程序)的流程图;
●说明程序的数据输入要求和输出结果的特点与结论;
●附源程序清单;
●实验的总结:
遇到的问题以及解决的办法、方法的优缺点;忌空、大话简述每一部分。
●对源程序的功能块做适当注释。
其他未尽事项按写报告的一般要求进行。
●报告统一采用A4纸正反面打印(正文采用5号字体,单倍行距)或手写,左侧装订。
●每人独立完成实验,如发现实验程序或报告的内容雷同,雷同双方(或多方)报告视为无效。
实验报告格式如附件提供的模板,提交的文档格式应严格按规定的模板格式(文字水印格式为“DS2014_学号_姓名”,如“DS2014_0312yyyxx_张三”)。
二、实验内容
实验一:
顺序表、单链表的定义、创建、插入和删除操作,将数据元素显示出来。
题目分析:
此题考查的是线性结构中的顺序表和单链表的基本操作。
首先说顺序表,是用内存中地址连续的一块存储空间存放线性表,而内存中地址空间本就是连续的,因此在定义了顺序表以后,只需申请一个指向首地址的指针即可,要想进行添加或删除只需移动指针所指位置找到需要修改的位置即可。
而对于单链表,由于其在内存中位置不连续,而由指针与数据构成一个结点,依次串联,因此修改操作中头指针发挥了巨大用处。
此题目在书中就有完整的参考程序代码,可以参照书上的代码进行编程。
程序思路:
顺序表:
首先定义顺序表,接着调用顺序表初始化函数SeqList*init_SeqList()申请一个长度为newSeqList[sizeof(SeqList)]的空间,接下来调用顺序表创建函数esta_SeqList(SeqList*L)来进行对顺序表的创建,此函数要求用户输入数组,以-1为结束标志,接下来要求用户进行插入操作,当表满以及插入位置错误时都有提示,接下来就是删除,程序最后会把顺序表的元素用for循环输出出来
其中比较重要的插入和删除函数流程图如下:
(使用流程图绘图软件绘制)
单链表:
首先依然是定义一个单链表,接着调用CREATE_SL(SLNODE*h)函数用尾插法建立单链表,使用while循环,要求用户输入数据,以-1为结束标志,接着调用前插算法Insert_LinkList(SLNODE*h,inti,intx)函数进行插入操作,此函数对错误操作都有考虑,接下来就调用Del_LinkList(SLNODE*h,inti)函数进行删除操作,对错误操作也有处理。
还有一个输出函数voidPrint_LinkList(SLNODE*h)用for循环对单链表的数据进行输出。
其中比较重要的插入函数流程图如下:
(使用流程图绘图软件绘制)
操作演示:
顺序表***************************
即将为您建立一个顺序表,请以-1结尾
请您输入一个整数
1
请您输入一个整数
2
请您输入一个整数
4
请您输入一个整数
-1
恭喜你,创建顺序表成功^_^
输入需插入的数据:
3
输入需插入的结点:
3
插入成功^-^
1234输入需删除的结点
1
删除成功^-^
顺序表元素为:
234
单链表*******************************
欢迎使用单链表程序,感谢伟大的尚林伟同学给你带来了方便
请输入一组数,以-1为结尾
1
2
4
-1
单链表创建成功^-^
输入需插入的数据:
3
输入需插入的结点:
3
插入成功^-^
链表h数据如下
1234
输入需删除的结点
4
删除成功^-^
链表h数据如下
123
源程序代码:
顺序表*******************************
//031240117尚林伟
#include
#defineSeqListstructlisttype
#defineMaxSize1000
SeqList//定义一个顺序表
{
intdata[MaxSize];
intlast;
};
SeqList*init_SeqList()//顺序表的初始化
{
SeqList*L;
L=newSeqList[sizeof(SeqList)];
L->last=-1;
returnL;
}
SeqList*esta_SeqList(SeqList*L)//建立一个顺序表
{
inti,x;
cout<<"即将为您建立一个顺序表,请以-1结尾"<for(i=0;x!
=-1;i++)
{
cout<<"请您输入一个整数"<cin>>x;
L->data[i]=x;
L->last++;
}
L->last--;
returnL;
}
intInsert_SeqList(SeqList*L,inti,intx)//顺序表插入操作
{
intj;
i=i-1;
if(L->last==MaxSize)
{
cout<<"很抱歉,顺序表已经满了-_-!
!
!
"<return(-1);
}
if(i<0||i>L->last)
{
cout<<"位置错误鸟-_-!
!
!
"<return0;
}
if((L->last+1)==0)
L->data[L->last+1]=x;
else
{
for(j=L->last;j>=i;j--)
L->data[j+1]=L->data[j];
L->data[i]=x;
}
L->last++;
return
(1);
}
intDelete_SeqList(SeqList*L,inti)//顺序表删除操作
{
intj;
i=i-1;
if(i<0||i>L->last)
{
cout<<"你个傻逼,第i个元素不存在-_-!
!
!
"<return(0);
}
for(j=i;j<=L->last-1;j++)
L->data[j]=L->data[j+1];
L->last--;
return
(1);
}
voidout_SeqList(SeqList*L)//顺序表元素的输出
{
inti;
if(L->last!
=-1)
{
for(i=0;i<=L->last;i++)
cout<data[i]<<'';
}
else
cout<<"顺序表为空"<}
voidmain()
{
SeqList*l;
inti,x;
l=init_SeqList();
esta_SeqList(l);
cout<<"恭喜你,创建顺序表成功^_^"<cout<<"输入需插入的数据:
"<cin>>x;
cout<<"输入需插入的结点:
"<cin>>i;
if(Insert_SeqList(l,i,x))
cout<<"插入成功^-^"<else
cout<<"插入失败-_-!
"<out_SeqList(l);
cout<<"输入需删除的结点"<cin>>i;
if(Delete_SeqList(l,i))
cout<<"删除成功^-^"<else
cout<<"删除失败-_-!
"<cout<<"顺序表元素为:
"<out_SeqList(l);
}
单链表*******************************
//031240117尚林伟
#include
#defineSLNODEstructnode
SLNODE//定义一个单链表
{
intdata;
SLNODE*next;
};
voidCREATE_SL(SLNODE*h)//尾插法创建一个单链表
{
SLNODE*p,*s;
intx;
h->next=NULL;
cout<<"欢迎使用单链表程序,感谢伟大的尚林伟同学给你带来了方便"<cout<<"请输入一组数,以-1为结尾"<cin>>x;
while(x!
=-1)
{
s=newSLNODE[sizeof(SLNODE)];
s->data=x;
if(h->next==NULL)
h->next=s;
else
p->next=s;
p=s;
cin>>x;
}
p->next=NULL;
}
intInsert_LinkList(SLNODE*h,inti,intx)//单链表的前插操作
{
SLNODE*p,*s;
intj;
p=h;j=0;
while(p->next!
=NULL&&j{
p=p->next;
j++;
}
if(j!
=i-1)
{
cout<<"i不存在不能插入!
!
!
"<return0;
}
else
{
s=newSLNODE[sizeof(SLNODE)];
s->data=x;
s->next=p->next;
p->next=s;
return1;
}
}
intDel_LinkList(SLNODE*h,inti)//单链表的删除操作
{
SLNODE*p,*s;
intj;
p=h;j=0;
while(p->next!
=NULL&&j{
p=p->next;
j++;
}
if(j!
=i-1)
{
cout<<"i不存在不能删除!
!
!
"<return0;
}
else
{
if(p->next==NULL)
{
cout<<"第i个节点不存在!
!
!
"<return0;
}
else
{
s=p->next;
p->next=s->next;
deletes;
return1;
}
}
}
voidPrint_LinkList(SLNODE*h)//输出链表数据
{
SLNODE*p;
p=h->next;
cout<<"链表h数据如下"<for(;p->next!
=NULL;p=p->next)
{
cout<data<<'\t';
}
cout<data<}
voidmain()//主函数
{
SLNODE*h;
inti,x;
h=newSLNODE[sizeof(SLNODE)];
h->next=NULL;
CREATE_SL(h);
cout<<"单链表创建成功^-^"<cout<<"输入需插入的数据:
"<cin>>x;
cout<<"输入需插入的结点:
"<cin>>i;
if(Insert_LinkList(h,i,x))
cout<<"插入成功^-^"<else
cout<<"插入失败-_-!
"<Print_LinkList(h);
cout<<"输入需删除的结点"<cin>>i;
if(Del_LinkList(h,i))
cout<<"删除成功^-^"<else
cout<<"删除失败-_-!
"<Print_LinkList(h);
}
实验二、二叉树的链式存储结构的数据结构定义、创建、先序/中序/后序遍历,并将结果序列输出。
题目分析:
本题考察的是二叉树的链式存储结构的运用,二叉树由一个根与左右两个结点构成,因此一个结点可用三个域来组成,除了一个数据域,还有两个指针域,分别用来指向该结点左子结点和右子结点的存储地址,由此,便可以把一个一个的结点结合起来形成二叉树。
当需要进行遍历时,只需按顺序访问结点并依次访问相应的左或右结点即可。
程序思路:
首先是对二叉树的定义,结构体中包含一个整形的数据以及该结构体的左右结点指针,接着调用Create()函数进行二叉树的建立,该函数利用递归调用的原理,会让你从左结点开始不断输入左结点的左结点,以0为结束标志,然后输入最左的结点的右结点,由此依次返回根结点。
接下来是先序遍历,从根节点开始,先输出左结点,再输出右结点。
中序遍历先输出左结点,接着是根结点,然后是右结点。
后序遍历先输出左结点,然后是右结点,最后输出根结点。
其中比较重要的三种遍历流程图如下:
(使用流程图绘图软件绘制)
操作演示:
二叉树*******************************
欢迎使用二叉树,请输入你心目中的结点数据吧(0表示空结点哟^_^)
1
输入左结点
2
输入左结点
0
输入右结点
0
输入右结点
3
输入左结点
0
输入右结点
0
先序遍历二叉树元素为
123
中序遍历二叉树元素为
213
后序遍历二叉树元素为
231
源程序代码:
二叉树*******************************
//031240117尚林伟
#include
#defineMAXNODE100
typedefstructbinode//定义二叉树的二叉链表
{
intdata;
structbinode*lchild,*rchild;
}BiTree;
BiTree*Create()//建立一棵二叉树
{
BiTree*bt;
intch;
cin>>ch;
if(ch==0)
{
bt=NULL;
}
else
{
bt=newbinode[sizeof(binode)];
bt->data=ch;
cout<<"输入左结点"<bt->lchild=Create();
cout<<"输入右结点"<bt->rchild=Create();
}
returnbt;
};
voidPreOrder(BiTree*bt)//先序遍历
{
if(bt==NULL)
return;
cout<data<<'\t';
PreOrder(bt->lchild);
PreOrder(bt->rchild);
}
voidInOrder(BiTree*bt)//中序遍历
{
if(bt==NULL)
return;
InOrder(bt->lchild);
cout<data<<'\t';
InOrder(bt->rchild);
}
voidPostOrder(BiTree*bt)//后序遍历
{
if(bt==NULL)
return;
PostOrder(bt->lchild);
PostOrder(bt->rchild);
cout<data<<'\t';
}
voidmain()//主函数
{
BiTree*bt;
cout<<"欢迎使用二叉树,请输入你心目中的结点数据吧(0表示空结点哟^_^)"<bt=Create();
cout<<"先序遍历二叉树元素为"<PreOrder(bt);
cout<cout<<"中序遍历二叉树元素为"<InOrder(bt);
cout<cout<<"后序遍历二叉树元素为"<PostOrder(bt);
cout<}
实验三、图的邻接表和邻接矩阵数据结构的定义、创建;图的深度优先遍历、广度优先遍历。
题目分析:
图是由非空的顶点和一个描述顶点之间联系——边的集合组成。
因此,图应该用结构体来定义,在c++语言中,学习了类的定义,如果用来做图,会变得很简单。
此题考察的主要是图的邻接矩阵以及邻接表的基本操作。
程序书上都有列举,但由于我学的是c++,因此要看懂书上的程序有一些困难,所以我上网搜索了一些资料,最后决定用c++语言来做。
程序思路:
图的邻接表:
首先需要对邻接表进行定义,我并没有只用一个结构体,而是用了三个来对邻接表中各数据进行了定义。
由于邻接表的储存方式需要用到队列,因此接下来就是对队列的定义,仿照书上的程序完成了对队列的定义后,接下来就是对图的创建,再然后是两种遍历方式的代码。
主函数开始,先定义一个表G,然后调用voidCreatAdjList()函数创建邻接表,此函数会要求用户依次输入顶点,边等信息,因为是无向图,所以有两次建立边表的过程。
接着要求用户选择一个定点,接着从这个顶点开始深度优先及广度优先遍历,并把结果显示出来。
其中比较重要的创建,先序遍历,后序遍历函数流程图如下:
(使用流程图绘图软件绘制)
图的邻接矩阵:
对邻接矩阵的做法我参考了网上查到的资料,决定用c++中的类来做。
首先定义一个图类,其中的元素除了顶点和边的信息外,还有一个创建函数voidcreatadj(),这样用一个类就把邻接矩阵的定义和创建都做好了。
类定义以后,只需编辑两个遍历函数即可。
主函数开始,先调用创建函数创建图,依然是让用户选择一个顶点开始深度优先遍历,同时用了一个for循环来进行多次遍历,每一个循环结束会询问用户是否继续遍历,选否,则退出for循环。
广度优先遍历原理与深度优先遍历一样。
其中比较重要的先序遍历,后序遍历函数流程图如下:
(使用流程图绘图软件绘制)
操作演示:
邻接表***************************
请输入顶点数和边数:
5
7
开始输入顶点表:
0
1
2
3
4
开始输入边表信息:
请输入边对应的顶点:
0
1
请输入边对应的顶点:
1
3
请输入边对应的顶点:
3
4
请输入边对应的顶点:
4
2
请输入边对应的顶点:
2
0
请输入边对应的顶点:
0
3
请输入边对应的顶点:
1
2
请输入开始遍历的顶点:
2
该图的深度优先遍历结果为:
21034
该图的广度优先遍历结果为:
201304
邻接矩阵*************************
请输入8个顶点信息
0
1
2
3
4
5
6
7
请输入第1条边,共15条边0
1
请输入第2条边,共15条边1
2
请输入第3条边,共15条边2
3
请输入第4条边,共15条边3
4
请输入第5条边,共15条边4
5
请输入第6条边,共15条边5
6
请输入第7条边,共15条边6
7
请输入第8条边,共15条边3
4
请输入第9条边,共15条边2
3
请输入第10条边,共15条边1
2
请输入第11条边,共15条边6
4
请输入第12条边,共15条边7
5
请输入第13条边,共15条边5
1
请输入第14条边,共15条边2
7
请输入第15条边,共15条边6
2
恭喜恭喜,图创建成功啦^_^
01001000
10100110
01010000
00101100
10010110
01011010
01001100
00000000
请输入深度优先遍历开始访问的顶点
4
从4出发的深度优先遍历序列为
3210456
继续进行深度优先遍历吗(1/2)?
2
请输入广度优先遍历开始访问的顶点
4
从4出发的广度优先遍历序列为
3245106
继续进行广度优先遍历吗(1/2)?
2
源程序代码:
邻接表***************************
//031240117尚林伟
#include
#defineMaxVerNum50
structedgenode//图的邻接表的定义
{
intendver;
intinform;
edgenode*edgenext;
};
structvexnode
{
charvertex;
edgenode*edgelink;
};
structGraph
{
vexnodeadjlists[MaxVerNum];
intvexnum;
intarcnum;
};
/*************************************/structQueueNode//队列的定义及相关函数的实现
{
intnData;
QueueNode*next;
};
structQueueList
{
QueueNode*front;
QueueNode*rear;
};
voidEnQueue(QueueList*Q,inte)
{
QueueNode*q=newQueueNode;
q->nData=e;
q->next=NULL;
if(Q==NULL)
return;
if(Q->rear==NULL)
Q->front=Q->rear=q;
else
{
Q->rear->next=q;
Q->rear=Q->rear->next;
}
}
voidDeQueue(QueueList*Q,int*e)
{
if(Q==NULL)
retu