图的遍历实验报告四.docx
《图的遍历实验报告四.docx》由会员分享,可在线阅读,更多相关《图的遍历实验报告四.docx(14页珍藏版)》请在冰豆网上搜索。
图的遍历实验报告四
数据结构试验报告
实验四
综合设计
实验题目:
树的遍历
专业班级:
计科系1507班
组长:
李煜(2015100733)
组员:
高干(2015100730)
张慧锋(2015100725)
王俊艳(2015100715)
2017年6月3日
实验报告
实验类型综合设计实验室软件实验室二
一、实验题目
树的遍历
二、实验目的和要求
实验目的:
1.使学生可以巩固所学的有关图的基本知识。
2.熟练掌握图的存储结构。
3.熟练掌握图的两种遍历算法。
4.进一步掌握图的结构及非线性特点。
5.进一步巩固对指针的使用,编写图的创建和遍历基本操作的实现程序。
实验要求:
1.无向图中的相关信息要从终端以正确的方式输入;
2.具体的输入和输出格式不限;
3.算法要具有较好的健壮性,对错误操作要做适当处理;
4.程序算法作简短的文字注释。
三、需求分析
很多问题都是建立在图的遍历的基础上实现的,所以必须有一个程序能够实现将图进行广度和深度遍历,必须对图的所有节点进行访问。
以无向图为例,以无向图的邻接表和邻接矩阵为存储结构,分别实现对图进行广度和深度遍历。
提供完整测试数据、原代码文件、提供系统运作流程图、数据传递及函数功能实现原理。
分析程序编写中产生的问题,并列出错误分析过程及解决方法。
四、概要设计
本次开发的“树的遍历”实现了上述程序功能,代码如下:
#include
#include
#defineMAX_VERTEX_NUM20
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
#defineTRUE1
#defineOK1
#defineFALSE0
#defineERROR0
#defineOVERFLOW-2
typedefintInfoType;
typedefintVertexType;
typedefintStatus;
typedefintQElemType;
typedefintSElemType;
typedefenum{DG,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向图,无向网}
boolvisited[MAX_VERTEX_NUM];
typedefstructArcNode
{
intadjvex;//该弧所指向的顶点在数组中的下标
structArcNode*nextarc;
InfoType*info;//该弧相关信息的指针
}ArcNode;
typedefstructVNode
{
VertexTypedata;//顶点信息
ArcNode*firstarc;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct
{
AdjListvertices;
intvexnum,arcnum;//图的当前顶点数和弧数
intkind;//图的种类标志
}ALGraph;
typedefstruct
{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
typedefstructQNode
{
QElemTypedata;
structQNode*next;
}QNode,*QueuePtr;
typedefstruct
{
QueuePtrfront;
QueuePtrrear;
}LinkQueue;
intLocateVex(ALGraphG,VertexTypev)
{//返回数组下标值
inti;
for(i=0;iif(G.vertices[i].data==v)
returni;
return-1;
}
voidCreateDN(ALGraph&G)
{//采用邻接表存储表示,构造有向图G(G.kind=DN)
inti,j,k;ArcNode*p;
VertexTypev1,v2;
G.kind=DN;
printf("输入顶点数:
");
scanf("%d",&G.vexnum);
printf("输入弧数:
");
scanf("%d",&G.arcnum);
printf("输入顶点:
\n");
for(i=0;i{//构造表头向量
scanf("%d",&G.vertices[i].data);
G.vertices[i].firstarc=NULL;//初始化指针
}
for(k=0;k{
printf("第%d条弧:
\n",k+1);
scanf("%d",&v1);
scanf("%d",&v2);//输入一条弧的始点和终点
i=LocateVex(G,v1);
j=LocateVex(G,v2);//确定v1和v2在G中位置
p=(ArcNode*)malloc(sizeof(ArcNode));//假定有足够空间
p->adjvex=j;
p->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p;
scanf("%d",&p->info);
}//for
}
StatusPush(SqStack&S,SElemTypee)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!
S.base)exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
returnOK;
}
StatusInitStack(SqStack&S)
{
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!
S.base)exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
returnOK;
}
StatusPop(SqStack&S,SElemType&e)
{
if(S.top==S.base)returnERROR;
e=*--S.top;returnOK;
}
StatusGetTop(SqStackS,SElemType&e)
{
if(S.top==S.base)returnERROR;
e=*(S.top-1);returnOK;
}
StatusStackEmpty(SqStackS)
{
if(S.top==S.base)returnTRUE;
returnFALSE;
}
StatusInitQueue(LinkQueue&Q)
{
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!
Q.front)exit(OVERFLOW);
Q.front->next=NULL;
returnOK;
}
StatusEnQueue(LinkQueue&Q,QElemTypee)
{
QueuePtrp=(QueuePtr)malloc(sizeof(QNode));
if(!
p)exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
returnOK;
}
StatusDeQueue(LinkQueue&Q,QElemType&e)
{
if(Q.front==Q.rear)returnERROR;
QueuePtrp=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
free(p);
returnOK;
}
StatusQueueEmpty(LinkQueueQ)
{
if(Q.front==Q.rear)
returnTRUE;
returnFALSE;
}
intFirstAdjVex(ALGraphG,intu)
{
if(!
G.vertices[u].firstarc)return-1;
returnLocateVex(G,G.vertices[u].firstarc->adjvex);
}
intNextAdjVex(ALGraphG,intu,intw)
{
ArcNode*p=G.vertices[u].firstarc;
while(p&&LocateVex(G,p->adjvex)!
=w)p=p->nextarc;
if(!
p)returnFirstAdjVex(G,u);
p=p->nextarc;
if(!
p)
return-1;
returnLocateVex(G,p->adjvex);
}
voidVisit(ALGraphG,intv)
{
printf("%2d",G.vertices[v].data);
}
voidDFSTraverse(ALGraphG)
{//按深度优先非递归遍历图G,使用辅助栈S和访问标志数组visited
intv,w;
SqStackS;
for(v=0;vInitStack(S);
for(v=0;vif(!
visited[v])
{//v尚未被访问
visited[v]=TRUE;
Visit(G,v);
Push(S,v);//v进栈
while(!
StackEmpty(S))
{
for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))
{
if(!
visited[w])
{Visit(G,w);
visited[w]=TRUE;
Push(S,w);
GetTop(S,v);
}//if
}//for
Pop(S,v);
GetTop(S,v);
}//while
}//if
printf("\n");
}
voidBFSTraverse(ALGraphG)
{//按广度优先非递归遍历图G,使用辅助队列Q和访问标志数组visited
intv,u,w;LinkQueueQ;
for(v=0;vvisited[v]=FALSE;
InitQueue(Q);
for(v=0;vif(!
visited[v])
{//v尚未被访问visited[v]=TRUE;
Visit(G,v);
EnQueue(Q,v);//v入队列
while(!
QueueEmpty(Q))
{
DeQueue(Q,u);//队头元素出队并置为u
for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))
if(!
visited[w])
{//w为u的尚未访问的邻接顶点
visited[w]=TRUE;
Visit(G,w);
EnQueue(Q,w);
}//if
}//while
}//if
printf("\n");
}
voidPrintDN(ALGraphG)
{
inti;
ArcNode*p;
printf("顶点:
\n");
for(i=0;iprintf("%2d",G.vertices[i].data);
printf("\n弧:
\n");
for(i=0;i{
p=G.vertices[i].firstarc;
if(p)
{
while(p)
{
printf("%d→%d(%d)\t",i,p->adjvex,p->info);
p=p->nextarc;
}
printf("\n");
}//if
}//for
}
voidmain()
{
ALGraphG;
CreateDN(G);
PrintDN(G);
printf("深度优先遍历:
");
DFSTraverse(G);
printf("广度优先遍历:
");
BFSTraverse(G);
}
本程序包含的各个模块详情介绍如下:
函数名
函数名(中文注释)
功能简介
main()
主函数
显示系统功能菜单,提供各功能的接口。
BFSTraverse()
广度遍历
使用辅助队列访问数组
PrintDN()
录入信息
输入弧顶点
Push()
存储
采用邻接表存储表示,构造有向图G
InitStack()
开辟存储节点
以指针方式开辟节点
各功能模块之间的调用关系如下:
五、使用说明
1、程序名为“数的遍历”,运行坏境为VisualC++,程序执行后显示“输入顶点数”;
2、输入顶点数后,根据提示输入弧数;
3、输入弧数后,根据提示依次输入各个顶点;
4、录完全部顶点后,根据提示依次输入各个弧,按enter键显示顶点,弧,深度优先遍历
和广度优先遍历。
六、调试分析
在本系统的编写过程中,我们遇到的主要问题及解决方案:
结构体设计不合理,影响了后续的函数编写,导致系统在数据处理时不能正确读取相关数据。
解决方案:
依据需求重新设计结构体,并增加了宏定义,重新编写函数中的各部分初始化语句,排查并修正错误。
测试结果
1、执行“树的遍历”程序后显示“输入顶点数”,此时键入顶点数为4。
2、键入顶点数为4后,根据提示按输入弧数为4:
3、输入弧数后,根据提示依次输入各个顶点为1、2、3、4:
4、录完全部顶点后,根据提示依次输入各个弧,按enter键显示出了顶点,弧,深度优先
遍历和广度优先遍历:
六、实验总结
1、通过这次实验,使我们基本上掌握了图的存储和遍历,让我弄清楚了如何用邻接矩
阵和邻接链表对图进行存储
2、深度优先遍历和广度优先遍历都有着各自的优点,通过程序逐步调试,可以慢慢的
理解这两种遍历方法的内涵和巧妙之处。
3、实验过程中,总体来说还算顺畅,但在编写过程中,要养成良好的编程习惯,以免
出错后浪费大量的时间在查错上。
4、本实验程序设计中,将程序分为五个模块,使得设计时思路清晰,实现时调试顺利,
各模块具有较好的可重用性,确实得到了一次良好的程序设计训练。
附录:
模块分工
李煜(2015100733):
编写EnQueue();DeQueue();main();
高干(2015100730):
编写InitQueue();StackEmpty();GetTop();
张慧锋(2015100725):
编写InitStack();CreateDN();LocateVex();
王俊艳(2015100715):
编写NextAdjVex();DFSTraverse();BFSTraverse();
全体成员:
结构体设计、系统流程分析、系统外观设计、实验报告