图的广度遍历课程设计报告Word文件下载.docx
- 文档编号:21783922
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:26
- 大小:601.05KB
图的广度遍历课程设计报告Word文件下载.docx
《图的广度遍历课程设计报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《图的广度遍历课程设计报告Word文件下载.docx(26页珍藏版)》请在冰豆网上搜索。
2)结构体、函数及说明
typedefstructArcNode//邻接表表结点
{
intadjvex;
//该弧所指向的顶点位置
structArcNode*nextarc;
//指向下一条弧的指针
//InfoType*info;
//该弧相关信息指针
}ArcNode;
typedefstructVNode//邻接表头结点
VertexTypedata;
//结点信息
ArcNode*firstarc;
//指向第一条依附该结点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct//图
AdjListVertices;
//邻接表头结点数组
intvexnum,arcnum;
//图的当前顶点数和弧数
intkind;
//图的种类标志(有向图:
0,无向图:
1)
}ALGraph;
voidprint(intv)//输出顶点信息
intFirstAdjVex(ALGraphG,intu)//在邻接表G中取第u个头结点
voidNextAdjVex(ALGraphG,intu,intw)//在邻接表G中取第u个头结点之后的结点w的下一结点
voidBFSTraverse(ALGraphG,queue<
int>
Q,boolvisited[],intm,intn,void(*Visit)(int))//使用辅助队列Q从邻接表结点m开始n结束广度遍历邻接表图G
3.
详细设计
1)遍历函数设计
//按广度优先非递归遍历图G。
使用辅助队列Q和访问标志数组visited。
while(!
Q.empty())Q.pop();
//置空的辅助队列Q
for(intv=m;
v<
n;
++v)
if(!
visited[v])//如果v尚未访问
{
visited[v]=true;
Visit(v);
//访问v
Q.push(v);
//v入队列
while(!
Q.empty())
{
intu=Q.front();
Q.pop();
//对头元素出队并置为u
for(intw=FirstAdjVex(G,u);
w>
=0;
w=NextAdjVex(G,u,w))//从以u为头结点的邻接表开始遍历到链表中的最后一个结点
if(!
visited[w])//w为u的尚未访问的邻接结点
{
visited[w]=true;
Visit(w);
//访问w
Q.push(w);
//w入队列
}//if
}//while
}//if
}//BFSTraverse*/
2)容错性方法设计
cout<
<
"
\n请输入图的弧数:
;
for(;
)
gets_s(s);
//以字符串形式接受所输入的数据
t=atoi(s);
//取出字符串中的整型
n=G.vexnum*(G.vexnum-1)/2;
//计算整型合理范围
if(G.kind==1)
n+=n;
//修正整型合理范围
if(t>
n||t<
1)//如果整型不在合理范围内
cout<
错误!
请输入一个大于0小于"
n+1<
的数:
//程序报错并返回循环重新输入
else//如果整型在范围内
break;
//跳出循环继续
}
G.arcnum=t;
//赋值
3)生成邻接表设计
\n请分别输入图的"
G.arcnum<
条弧(弧尾,弧头):
endl;
for(inti=0;
i<
G.arcnum;
i++)
intn1,n2;
for(;
{
弧"
i+1<
:
\t"
gets_s(s);
t=atoi(s);
//取出字符串中的整型
strcpy_s(c,s+2);
//去掉字符串中的前两个字符
n=atoi(c);
if(t>
G.vexnum||t<
1||n>
G.vexnum||n<
1||t==n)//如果整型不在合理范围内
cout<
请分别输入两个大于0小于"
G.vexnum+1<
\n\n"
else//如果整型在范围内
break;
//跳出循环继续
}
n1=t-1;
n2=n-1;
//修正赋值
if(!
visited[n1])//如果n1后没有结点
visited[n1]=true;
//设置n1后已有结点
G.Vertices[n1].firstarc=newArcNode;
//在n1后增加新结点
G.Vertices[n1].firstarc->
adjvex=n2;
//结点赋值为n2
nextarc=NULL;
//设置n2之后的结点为空
else//如果n1后已有结点
ArcNode*p=G.Vertices[n1].firstarc;
//新建结点指针
while((p->
nextarc)!
=NULL)
p=p->
nextarc;
//将指针指向链表中最后一个结点
p->
nextarc=newArcNode;
//在最后增加一个新结点
nextarc->
//给结点赋值n2
nextarc=NULL;
//设置n2之后的结点为空
4)邻接表遍历设计
\n\n请输入遍历的起点:
//以字符串形式接受所输入的数据
1)//如果整型不在合理范围内
//程序报错并返回循环重新输入
t-=1;
\n广度遍历顺序:
\n"
queue<
Q;
//定义辅助队列Q
for(intj=0;
j<
G.vexnum;
++j)
visited[j]=false;
//访问标志置0
BFSTraverse(G,Q,visited,t,G.vexnum,print);
//从输入的遍历起点到最后一个邻接表头结点遍历邻接表
BFSTraverse(G,Q,visited,0,t,print);
//从第一个邻接表头结点到输入的邻接表头结点遍历邻接表,防止还有连通分量尚未遍历
4.
调试分析和测试结果
编译、运行及调试环境:
MicrosoftVisualStudio2010Ultimate
1)调试分析
一.在求图的第u个顶点,与其相邻的一系列顶点中,第w个顶点的下一个顶点时,若是求最后一个顶点的下一个顶点时,因为是空指针所以返回值为0,程序误以为是第一个顶点,再求下一个顶点时便报错。
原因是判断条件没有写好,于是增加判断,当指针为空时返回-1。
修改判断条件后,函数正常运行。
二.在输入图信息的时候,若输入非法字符,程序会异常终止。
例如程序要求输入一个整型,用户却输入了一个字母,这时候会出现异常。
只是程序是否健壮性的一个体现。
先用字符串接收字符,转换成整型后再判断是否符合要求。
如果不符合便提示用户按要求重新输入。
还有其他一些类似的输入异常,都是采用类似的处理方法。
三.作为一个完整的程序,友好的界面是必须的。
因次程序中适当地采用系统中的清屏命令,使得界面更加简洁,明了。
2)测试结果
a)测试案例:
案例一案例二
b)测试过程与截图:
i.容错性测试:
在输入字母、符号、或不符合要求的数字时,提示错误并要求重新正确输入。
(截图1.1~截图1.7)
截图1.1
截图1.2
截图1.3
截图1.4
截图1.5
截图1.6
截图1.7
ii.
无向图(案例一)测试:
将测试案例一的数据输入程序,从第一个顶点开始遍历,结果如截图2.1所示。
截图2.1
输入y表示要继续遍历该图后,程序清屏,再次打印邻接表,并要求再次输入遍历起点,如截图2.2所示。
截图2.2
输入2后,打印从第二个顶点遍历的顺序,输入n停止继续遍历该图,如截图2.3所示。
截图2.3
iii.
有向图(案例二)测试:
输入y表示继续输入其他图进行遍历后,程序清屏,并要求再次输入一个图,将测试案例2的数据输入程序后,从第一个顶点遍历,如截图3.1所示。
截图3.1
输入y表示要继续遍历该图后,程序清屏,再次打印邻接表,并要求再次输入遍历起点。
输入4后,打印从第四个顶点遍历的顺序,输入n停止继续遍历该图。
再次输入n停止继续输入其他图进行遍历,程序结束,如截图3.2所示。
截图3.2
5.
总结
通过这一个课程设计,使我对图的广度优先遍历算法有了深度的了解。
在编程过程中也遇到了一些问题,基本上都一一解决了。
但是由于能力有限,程序中还有一些尚未解决的问题。
例如,如何能完全解决输入异常。
这说明今后还需要继续努力。
参考文献
a.图书类的参考文献
1.谭浩强·
C语言程序设计·
(第2版)·
清华大学出版社,出版年:
2009引用部分起止页码:
50-51,248-258。
2.陈维兴,林小茶·
C++面向对象程序设计教程·
(第3版)·
260-273。
3.严蔚敏,吴伟民·
数据结构·
(C语言版)·
2010引用部分起止页码:
156-170。
4.梁旭,谷晓琳,黄明·
C语言课程设计·
电子工业出版社,出版年:
21-24。
b.翻译图书类的参考文献
1.埃克尔著·
C++编程思想·
刘宗田等译·
机械工业出版社,出版年:
2003。
c.网站的名称
谷歌:
www.G
XX:
附录
程序源码:
//题目十一.图的广度遍历
//问题描述:
对任意给定的图(顶点数和边数自定),建立它的邻接表并输出,
//然后利用队列的五种基本运算(置空队列、进队、出队、取队头元素、判队空)实现图的广度优先搜索遍历。
#include<
iostream>
queue>
#defineMAX_VERTEX_NUM101
#defineVertexTypeint
usingnamespacestd;
typedefstructArcNode//邻接表表顶点
typedefstructVNode//邻接表头顶点
//顶点信息
//指向第一条依附该顶点的弧的指针
//邻接表头顶点数组
cout<
v+1<
"
}
intFirstAdjVex(ALGraphG,intu)//在邻接表G中取第u个头顶点
if(G.Vertices[u].firstarc==NULL)
return-1;
returnG.Vertices[u].firstarc->
adjvex;
intNextAdjVex(ALGraphG,intu,intw)//在邻接表G中取第u个头顶点之后的顶点w的下一顶点
ArcNode*p=G.Vertices[u].firstarc;
while(w!
=p->
adjvex)
p=p->
if(p->
nextarc==NULL)return-1;
returnp->
Q,boolvisited[],intm,intn,void(*Visit)(int))//使用辅助队列Q从邻接表顶点m开始n结束广度遍历邻接表图G
visited[v])//v尚未访问
w=NextAdjVex(G,u,w))
visited[w])//w为u的尚未访问的邻接顶点
intmain()
intt,n;
chars[10],c[10];
ALGraphG;
do
{
system("
cls"
);
cout<
请输入图的类型(有向图输1,无向图输2):
for(;
gets_s(s);
t=atoi(s);
if(t!
=1&
&
t!
=2)
cout<
请输入半角数字\"
1\"
或\"
2\"
else
break;
}
G.kind=t;
\n请输入图的顶点数:
if(t>
99||t<
请输入一个大于0小于100的数:
G.vexnum=t;
boolvisited[MAX_VERTEX_NUM];
for(inti=0;
visited[i]=false;
G.Vertices[i].firstarc=NULL;
if(G.kind==1)
else
strcpy_s(c,s);
t=atoi(c);
1||t==n)
else
visited[n1])
else
\n请输入图的边数:
条边(顶点1,顶点2):
边"
visited[n2])
visited[n2]=true;
G.Vertices[n2].firstarc=newArcNode;
G.Vertices[n2].firstarc->
adjvex=n1;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 图的广度遍历 课程设计报告 广度 遍历 课程设计 报告