图遍历的演示实习报告Word文档下载推荐.docx
《图遍历的演示实习报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《图遍历的演示实习报告Word文档下载推荐.docx(19页珍藏版)》请在冰豆网上搜索。

图G存在,v是G中顶点
返回v的值
FirstAjvex(G,v>
返回v的第一个邻接顶点,若顶在图中没有邻接顶点,则返回为空
NextAjvex(G,v,w>
图G存在,v是G中顶点,w是v的邻接顶点
返回v的下一个邻接顶点,若w是v的最后一个邻接顶点,则返回空
DeleteVexx(&
G,v>
删除顶点v已经其相关的弧
DFSTraverse(G,visit(>
>
图G存在,visit的顶点的应用函数
对图进行深度优先遍历,在遍历过程中对每个结点调用visit函数一次,一旦visit失败,则操作失败b5E2RGbCAP
BFSTraverse(G,visit(>
对图进行广度优先遍历,在遍历过程中对每个结点调用visit函数一次,一旦visit失败,则操作失败p1EanqFDPw
}ADTGraph
2、设定栈的抽象数据类型:
ADTStack{
数据对象:
D={ai|ai∈CharSet,i=1,2,……,n,n≥0}
数据关系:
R1={<
ai-1,ai>
|ai-1,ai∈D,i=2,……,n}
基本操作:
InitStack(&
S>
操作结果:
构造一个空栈S。
DestroyStack(&
初始条件:
栈S已存在。
操作结果:
栈S被销毁。
Push(&
S,e>
。
初始条件:
在栈S的栈顶插入新的栈顶元素e。
Pop(&
删除S的栈顶元素,并以e返回其值。
StackEmpty(S>
若S为空栈,则返回TRUE,否则返回FALSE。
}ADTStack
3、设定队列的抽象数据类型:
ADTQueue{
数据对象:
D={ai|ai属于Elemset,i=1,2….,n,n>
=0}
数据关系:
|ai-1,ai属于D,i=1,2,…,n}
约定ai为端为队列头,an为队列尾
基本操作:
InitQueue(&
Q>
构造一个空队列Q
DestryoQueue(&
队列Q已存在。
队列Q被销毁,不再存在。
EnQueue(&
Q,e>
队列Q已经存在
插入元素e为Q的新的队尾元素
DeQueue(&
Q,&
E>
Q为非空队列
删除Q的队尾元素,并用e返回其值
QueueEmpty(Q>
队列已经存在
若队列为空,则返回TRUE,否则返回FLASE
}ADTQueue
4、本程序包含九个模块:
1)主程序模块
voidmain(>
{
手动构造一个图;
从文件导入一个图;
显示图的信息;
进行深度优先遍历图;
进行广度优先遍历图;
保存图到一个文件;
寻找路径;
销毁一个图;
};
2)手动构造一个图-自己输入图的顶点和边生成一个图;
3)从文件导入一个图;
4)显示图的信息-打印图的所有顶点和边;
5)进行深度优先遍历图-打出遍历的结点序列和边集;
6)进行广度优先遍历图-打出遍历的结点序列和边集;
7)保存图到一个文件;
8)寻找从起点到终点,但中间不经过某点的所有简单路径;
9)销毁图。
三、详细设计
10)顶点,边和图类型
#defineMAX_INFO10/*相关信息字符串的最大长度+1*/
#defineMAX_VERTEX_NUM20/*图中顶点数的最大值*/
typedefcharInfoType。
/*相关信息类型*/
typedefcharVertexType。
/*字符类型*/
typedefenum{unvisited,visited}VisitIf。
typedefstructEBox{
VisitIfmark。
/*访问标记*/
intivex,jvex。
/*该边依附的两个顶点的位置*/
structEBox*ilink,*jlink。
/*分别指向依附这两个顶点的下一条边*/DXDiTa9E3d
InfoType*info。
/*该边信息指针*/
}EBox。
typedefstruct{
VertexTypedata。
EBox*firstedge。
/*指向第一条依附该顶点的边*/
}VexBox。
VexBoxadjmulist[MAX_VERTEX_NUM]。
intvexnum,edgenum。
/*无向图的当前顶点数和边数*/RTCrpUDGiT
}AMLGraph。
图的基本操作如下:
intLocateVex(AMLGraphG,VertexTypeu>
;
//查G和u有相同特征的顶点,若存在则返回该顶点在无向图中位置。
否则返回-1。
VertexType&
GetVex(AMLGraphG,intv>
//以v返回邻接多重表中序号为i的顶点。
intFirstAdjVex(AMLGraphG,VertexTypev>
//返回v的第一个邻接顶点的序号。
若顶点在G中没有邻接顶点,则返回-1。
intNextAdjVex(AMLGraphG,VertexTypev,VertexTypew>
5PCzVD7HxA
//返回v的(相对于w的>
下一个邻接顶点的序号若w是v的最后一个邻接点,则返回-1。
voidCreateGraph(AMLGraph&
//采用邻接多重表存储结构,构造无向图G。
StatusDeleteArc(AMLGraph&
G,VertexTypev,VertexTypew>
jLBHrnAILg
//在G中删除边<
v,w>
StatusDeleteVex(AMLGraph&
G,VertexTypev>
//在G中删除顶点v及其相关的边。
voidDestroyGraph(AMLGraph&
//销毁一个图
voidDisplay(AMLGraphG>
//输出无向图的邻接多重表G。
voidDFSTraverse(AMLGraphG,VertexTypestart,int(*visit>
(VertexType>
xHAQX74J0X
//从start顶点起,<
利用栈非递归)深度优先遍历图G。
voidBFSTraverse(AMLGraphG,VertexTypestart,int(*Visit>
LDAYtRyKfE
//从start顶点起,广度优先遍历图G。
voidMarkUnvizited(AMLGraphG>
//置边的访问标记为未被访问。
其中部分操作的伪码算法如下:
{/*采用邻接多重表存储结构,构造无向图G*/
DestroyGraph(G>
/*如果图不空,先销毁它*/
输入无向图的顶点数G.vexnum;
输入无向图的边数G.edgenum;
输入顶点的信息IncInfo;
依次输入无向图的所有顶点;
for(k=0。
k<
G.edgenum。
++k>
/*构造表结点链表*/
{
读入两个顶点va、vb;
i=LocateVex(G,va>
/*一端*/
j=LocateVex(G,vb>
/*另一端*/
p=(EBox*>
malloc(sizeof(EBox>
p->
mark=unvisited。
/*设初值*/
ivex=i。
jvex=j。
info=NULL。
ilink=G.adjmulist[i].firstedge。
/*插在表头*/
G.adjmulist[i].firstedge=p。
jlink=G.adjmulist[j].firstedge。
G.adjmulist[j].firstedge=p。
}
}
{/*输出无向图的邻接多重表G*/
MarkUnvizited(G>
输出无向图的所有顶点;
for(i=0。
i<
G.vexnum。
i++>
p=G.adjmulist[i].firstedge。
while(p>
if(p->
ivex==i>
/*边的i端与该顶点有关*/
if(!
p->
mark>
/*只输出一次*/
cout<
<
G.adjmulist[i].data<
'
-'
G.adjmulist[p->
jvex].data<
ends。
Zzz6ZB2Ltk
mark=visited。
p=p->
ilink。
else/*边的j端与该顶点有关*/
cout<
ivex].data<
dvzfvkwMI1
jlink。
endl。
rqyn14ZNXI
{/*从start顶点起,深度优先遍历图G(非递归算法>
*/
InitStack(S>
w=LocateVex(G,start>
/*先确定起点start在无向图中的位置*/
for(v=0。
v<
v++>
Visited[v]=0。
/*置初值*/
Visited[(v+w>
%G.vexnum]>
Push(S,(v+w>
%G.vexnum>
/*未访问,就进栈*/
while(!
Pop(S,u>
Visited[u]>
Visited[u]=1。
/*未访问的标志设为访问状态,并输出它的值*/
visit(G.adjmulist[u].data>
for(w=FirstAdjVex(G,G.adjmulist[u].data>
w>
=0。
w=NextAdjVex(G,G.adjmulist[u].data,G.adjmulist[w].data>
EmxvxOtOco
Visited[w]>
Push(S,w>
DestroyStack(S>
/*销毁栈,释放其空间*/
SixE2yXPq5
{/*从start顶点起,广度优先遍历图G*/
for(v=0。
/*置初值*/
InitQueue(Q>
z=LocateVex(G,start>
Visited[(v+z>
/*v尚未访问*/
Visited[(v+z>
%G.vexnum]=1。
/*设置访问标志为TRUE(已访问>
*/6ewMyirQFL
Visit(G.adjmulist[(v+z>
%G.vexnum].data>
EnQueue(Q,(v+z>
/*队列不空*/
DeQueue(Q,u>
w=NextAdjVex(G,G.adjmulist[u].data,G.adjmulist[w].data>
kavU42VRUs
Visited[w]=1。
Visit(G.adjmulist[w].data>
EnQueue(Q,w>
DestroyQueue(Q>
/*销毁队列,释放其占用空间*/
2、栈类型
#defineSTACK_INIT_SIZE100/*存储空间初始分量*/
#defineSTACKINCREMENT10/*存储空间分配增量*/
typedefintSElemType。
SElemType*base。
SElemType*top。
/*栈顶指针*/
intstacksize。
}SqStack。
栈的基本操作如下:
StatusInitStack(SqStack&
//构造一个空栈S。
StatusDestroyStack(SqStack&
//销毁栈S(无论空否均可>
StatusPush(SqStack&
S,SElemTypee>
//在S的栈顶插入新的栈顶元素e。
StatusPop(SqStack&
S,SElemType&
e>
//删除S的栈顶元素并以e带回其值。
StatusStackEmpty(SqStackS>
//若S为空栈,则返回TRUE,否则返回FALSE。
3、队列类型
typedefintQelemType;
typedefstructQNode{
QElemTypedata。
structQNode*next。
}QNode,*QueuePtr。
QueuePtrfront。
QueuePtrrear。
/*队头、队尾指针*/
}LinkQueue。
队列的基本操作如下:
StatusInitQueue(LinkQueue&
//构造一个空队列Q。
StatusDestroyQueue(LinkQueue&
//销毁队列Q(无论空否均可>
StatusQueueEmpty(LinkQueueQ>
//若Q为空队列,则返回1,否则返回-1。
StatusEnQueue(LinkQueue&
Q,QElemTypee>
//插入元素e为Q的新的队尾元素。
StatusDeQueue(LinkQueue&
Q,QElemType&
//若队列不空,删除Q的队头元素,用e返回其值,并返回1,否则返回-1。
4、生成树类型:
typedefstructCSNode{
structCSNode*firstchild,*nextsibling。
}CSNode,*CSTree。
/*树的二叉链表(孩子-兄弟>
存储结构*/
生成树的操作:
voidDFSTree(AMLGraphG,intv,CSTree&
DT>
//从第v个顶点出发深度遍历图G,建立以DT为根的生成树。
voidDFSForest(AMLGraphG,VertexTypestart,CSTree&
y6v3ALoS89
//建立图G的深度优先生成森林的(最左>
孩子(右>
兄弟链表DT。
voidPrintTraverse(CSTreeT>
//打印图G的遍历生成树的边。
voidPrintAllTraverse(CSTreeT>
//打印图G的遍历生成森林的边。
voidBFSTree(AMLGraphG,intv,CSTree&
BT>
//从第v个顶点出发广度遍历图G,建立以BT为根的生成树。
voidBFSForest(AMLGraphG,VertexTypestart,CSTree&
M2ub6vSTnP
//建立图G的广度优先生成森林的(最左>
兄弟链表BT。
voidPrintCSTree(CSTreeT,inti>
//用凹入表方式打印一棵以孩子-兄弟链表为存储结构的树。
voidPrintCSForest(CSTreeT>
//用凹入表方式打印一棵以孩子-兄弟链表为存储结构的森林。
{/*从第v个顶点出发深度遍历图G,建立以DT为根的生成树*/
first=1。
Visited[v]=1。
for(w=FirstAdjVex(G,G.adjmulist[v].data>
w=NextAdjVex(G,G.adjmulist[v].data,G.adjmulist[w].data>
0YujCfmUCw
p=(CSTree>
malloc(sizeof(CSNode>
/*分配孩子结点*/
strcpy(p->
data,G.adjmulist[w].data>
firstchild=NULL。
nextsibling=NULL。
if(first>
/*w是v的第一个未被访问的邻接顶点是根的左孩子结点*/
DT->
firstchild=p。
first=0。
else/*w是v的其他未被访问的邻接顶点是上一邻接顶点的右兄弟结点*/
q->
nextsibling=p。
q=p。
DFSTree(G,w,q>
/*从第w个顶点出发深度优先遍历图G,建立子生成树q*/
{/*从第v个顶点出发广度遍历图G,建立以BT为根的生成树*/
r=BT。
i=j=0。
Visited[v]=1。
EnQueue(Q,v>
/*先把第一个顶点入队列*/
eUts8ZQVRd
r->
first=0。
cur[i++]=p。
/*用一个数组指针保存生成树的根*/
r=cur[j++]。
/*回朔到上一棵生成树的根*/
{/*用凹入表方式打印一棵以孩子-兄弟链表为存储结构的树*/
for(j=1。
j<
=i。
j++>
ends<
/*留出i个空格以表现层*/
T->
data<
/*打印元素,换行*/
for(p=T->
firstchild。
p。
nextsibling>
PrintCSTree(p,i+1>
/*打印子树*/
{/*用凹入表方式打印一棵以孩子-兄弟链表为存储结构的森树*/
for(p=T。
"
第"
i++<
个树:
PrintCSTree(p,0>
5、主程序和其他伪码算法
显示菜单;
输入功能选择键;
switch(flag>
case1:
case2:
case3:
case4:
case5:
case6:
case7:
case8:
销毁图;
case9:
退出程序;
销毁图;
intVisited[MAX_VERTEX_NUM]。
/*访问标志数组(全局量>
*/
voidAllPath(AMLGraphG,VertexTypestart,VertexTypenopass,VertexTypeend