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