图的遍历实验报告四Word下载.docx
- 文档编号:16410135
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:14
- 大小:69.94KB
图的遍历实验报告四Word下载.docx
《图的遍历实验报告四Word下载.docx》由会员分享,可在线阅读,更多相关《图的遍历实验报告四Word下载.docx(14页珍藏版)》请在冰豆网上搜索。
本次开发的“树的遍历”实现了上述程序功能,代码如下:
#include<
stdio.h>
stdlib.h>
#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;
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
typedefstructQNode
QElemTypedata;
structQNode*next;
}QNode,*QueuePtr;
QueuePtrfront;
QueuePtrrear;
}LinkQueue;
intLocateVex(ALGraphG,VertexTypev)
{//返回数组下标值
inti;
for(i=0;
i<
MAX_VERTEX_NUM;
++i)
if(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);
输入弧数:
G.arcnum);
输入顶点:
\n"
G.vexnum;
++i)
{//构造表头向量
scanf("
G.vertices[i].data);
G.vertices[i].firstarc=NULL;
//初始化指针
}
for(k=0;
k<
G.arcnum;
++k)
{
printf("
第%d条弧:
k+1);
v1);
v2);
//输入一条弧的始点和终点
i=LocateVex(G,v1);
j=LocateVex(G,v2);
//确定v1和v2在G中位置
p=(ArcNode*)malloc(sizeof(ArcNode));
//假定有足够空间
p->
adjvex=j;
nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p;
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.top=S.base;
S.stacksize=STACK_INIT_SIZE;
StatusPop(SqStack&
S,SElemType&
e)
if(S.top==S.base)returnERROR;
e=*--S.top;
StatusGetTop(SqStackS,SElemType&
e)
e=*(S.top-1);
StatusStackEmpty(SqStackS)
if(S.top==S.base)returnTRUE;
returnFALSE;
StatusInitQueue(LinkQueue&
Q)
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
Q.front)exit(OVERFLOW);
Q.front->
next=NULL;
StatusEnQueue(LinkQueue&
Q,QElemTypee)
QueuePtrp=(QueuePtr)malloc(sizeof(QNode));
p)exit(OVERFLOW);
p->
data=e;
Q.rear->
next=p;
Q.rear=p;
StatusDeQueue(LinkQueue&
Q,QElemType&
if(Q.front==Q.rear)returnERROR;
QueuePtrp=Q.front->
next;
e=p->
data;
next=p->
if(Q.rear==p)
Q.rear=Q.front;
free(p);
StatusQueueEmpty(LinkQueueQ)
if(Q.front==Q.rear)
returnTRUE;
intFirstAdjVex(ALGraphG,intu)
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;
p)returnFirstAdjVex(G,u);
p=p->
p)
return-1;
returnLocateVex(G,p->
voidVisit(ALGraphG,intv)
%2d"
G.vertices[v].data);
voidDFSTraverse(ALGraphG)
{//按深度优先非递归遍历图G,使用辅助栈S和访问标志数组visited
intv,w;
SqStackS;
for(v=0;
v<
v++)visited[v]=FALSE;
InitStack(S);
++v)
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
}
voidBFSTraverse(ALGraphG)
{//按广度优先非递归遍历图G,使用辅助队列Q和访问标志数组visited
intv,u,w;
LinkQueueQ;
visited[v]=FALSE;
InitQueue(Q);
++v)
if(!
visited[v])
{//v尚未被访问visited[v]=TRUE;
EnQueue(Q,v);
//v入队列
QueueEmpty(Q))
DeQueue(Q,u);
//队头元素出队并置为u
for(w=FirstAdjVex(G,u);
w=NextAdjVex(G,u,w))
{//w为u的尚未访问的邻接顶点
visited[w]=TRUE;
Visit(G,w);
EnQueue(Q,w);
}//if
}//while
voidPrintDN(ALGraphG)
ArcNode*p;
顶点:
for(i=0;
i<
++i)
G.vertices[i].data);
\n弧:
p=G.vertices[i].firstarc;
if(p)
{
while(p)
{
printf("
%d→%d(%d)\t"
i,p->
adjvex,p->
p=p->
}
printf("
voidmain()
ALGraphG;
CreateDN(G);
PrintDN(G);
深度优先遍历:
DFSTraverse(G);
广度优先遍历:
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();
全体成员:
结构体设计、系统流程分析、系统外观设计、实验报告
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 遍历 实验 报告