求无向图中求两点间的所有简单路径实验报告Word格式.docx
《求无向图中求两点间的所有简单路径实验报告Word格式.docx》由会员分享,可在线阅读,更多相关《求无向图中求两点间的所有简单路径实验报告Word格式.docx(14页珍藏版)》请在冰豆网上搜索。
![求无向图中求两点间的所有简单路径实验报告Word格式.docx](https://file1.bdocx.com/fileroot1/2023-1/29/ce4cdfb7-baf8-4603-9018-580829320cb0/ce4cdfb7-baf8-4603-9018-580829320cb01.gif)
00010003
请输入请输入需查询所有路径的两所城市的名称:
从城市0001到0003的所有简单路径如下:
001->
003
002->
所有路径已存入文件中。
001002003
2
001002
002003
001->
0
从城市0001到0003的无简单路径
4
001002003004
5
003004
请输入第四对连接城市的高速公路:
001004
请输入第五对连接城市的高速公路:
001003
00010004
0001->
0004
0003->
0002->
-1
结束程序
二.概要设计
抽象数据类型
因为各个城市间的是否有高速公路连通的关系是非线性的,而且具有结构网状特性,并且高速公路是无向的,所以选择无向图来表示各个城市间的连通关系。
图的ADT设计:
数据对象:
G=(V,E),其中V表示顶点集合,E表示边集合
数据关系:
VR={<
v,w>
|v,w∈V且P(v,w)}
<
表示从v到w的一条弧,v为弧头,w为弧尾。
基本操作:
intn();
//图中顶点个数
inte();
//图边数
intfirst(int);
//该点的第一条临边
intnext(int,int);
//该点的第二条临边
voidsetEdge(int,int,int);
//为边设置权值
voidsetMark(int,int);
//设置该顶点的标志值
intgetMark(int);
//获得该顶点的标志值
图的顶点ADT设计:
数据对象:
城市编号(占3位的字母数字串)
数据关系:
{vi|i=1,2,3……n}
intposition();
//获取顶点位置
算法基本思想
当用户输入完毕后,根据各城市间相应的关系构建一个无向图,并使用一个临接矩阵存储该图。
考虑使用基于深度优先思想,在搜素过程中,每当访问一个节点,DFS就会递归访问它的所有未被访问的相邻节点。
并通过相应的设置标志的方式使最终能不重复地走遍所有的简单路径。
最后输出这些路径即可。
程序基本流程
该程序主要包括四个模块:
输入模块:
由用户输入城市总数,城市编号,高速公路编号;
构建与存储模块:
根据用户的输入构建无向图,并使用临接矩阵存储图;
访问模块:
对该图进行深度优先搜索,得到所有路径;
输出模块:
输出所有路径。
三.详细设计
物理数据类型
边的实现:
classEdge
{
public:
intvertex,weight;
Edge(){vertex=-1;
weight=-1;
}
Edge(intv,intw){vertex=v;
weight=w;
}
};
图的相邻矩阵实现:
classGraphm
private:
intnumVertex,numEdge;
int**matrix;
int*mark;
Graphm(intnumVert){
inti,j;
numVertex=numVert;
//顶点数
numEdge=0;
mark=newint[numVert];
for(i=0;
i<
numVertex;
i++)
mark[i]=0;
//每一个顶点的标志值初始化为0
matrix=(int**)newint*[numVertex];
matrix[i]=newint*[numVertex];
for(i=0;
for(j=0;
j<
j++)matrix[i][j]=0;
}
~Graphm()
{
delete[]mark;
for(inti=0;
delete[]matrix[i];
delete[]matrix;
}//析构函数
intn(){returnnumVertex;
}//顶点个数
intfirst(intv)//该顶点的第一条邻边
inti;
if(matrix[v][i]!
=0)returni;
returni;
}
intnext(intv1,intv2)//获得v1的邻居v2
{inti;
for(i=v2+1;
if(matrix[v1][i]!
returni;
voidsetEdge(intv1,intv2)//设置有向图的边
{
if(matrix[v1][v2]==0)
numEdge++;
matrix[v1][v2]=1;
intgetMark(intv)//获取顶点标记的值
{returnmark[v];
intsetMark(intv,intval)//设置访问的标记{mark[v]=val;
DFS的实现:
voidDFS(Graph*G,intv)
PreVisit(G,v);
G->
setMark(v,1);
for(intw=G->
first(v);
w<
n();
w=G->
next(v,w))
if(G->
getMark(w)==0)
DFS(G,w);
PostVisit(G,v);
算法具体步骤
根据用户的输入,构建一个无向图,并使用一个临接矩阵存储该图。
对该图进行深度优先搜索,并通过相应的设置标志的方式使最终能不重复地走遍所有的简单路径。
得到所有路径后,输出这些路径即可。
函数调用关系
输入
建图与存图临接矩阵存储
主程序DFS搜索
输出
算法时空分析
在表的存储中,临接矩阵的时间代价是Θ(|V2|),而在无向图中,DFS从两个方向处理每条边,每个顶点都必须被访问,且只能被访问一次,因此时间代价是Θ(|V|+|E|)。
所以该算法总时间代价是Θ(|V|2)。
输入输出格式
输入:
cin>
>
cityNum;
i++)
city[i];
cin>
roadNum;
roadName;
请输入要查询路径的两座城市编号:
输出:
001到003的所有路径如下:
四.调试分析
在实际编程中,程序曾陷入过死循环,尝试了一些方法仍然没有解决,最后使用了goto语句才解决了这个问题
五.测试结果
六.用户使用说明
1.该程序可以通过构建一个有向图来实现查找两城市间的所有简单路径的功能;
2.使用该程序时,首先按照要求输入各类参数,若输入有误,系统提示输入有误,并重新输入;
3.最后的结果将直接输出在DOS界面。
七.实验心得
通过该实验,我掌握了图的深度优先搜索的方法
代码:
graph.h文件:
#include<
iostream>
string>
queue>
usingnamespacestd;
boolvisited[100];
intpath[100];
classArcNode
intadjvex;
ArcNode*nextarc;
classVexNode
stringdata;
ArcNode*firstarc;
classGraph
VexNodevertices[100];
intvexnum;
intarcnum;
Graph()
vexnum=0;
arcnum=0;
~Graph(){delete[]vertices;
intgetArcnum()
returnarcnum;
intGetVexNum()
returnvexnum;
intPosition(stringv)
for(inti=0;
i<
vexnum;
i++)
if(vertices[i].data==v)
returni;
return-1;
voidBuild_Graph()
//构造无向图
stringv1,v2;
inti,j,k;
cout<
<
"
输入城市个数:
"
;
cin>
vexnum;
cin>
arcnum;
输入城市名称:
for(i=0;
{
cin>
vertices[i].data;
vertices[i].firstarc=NULL;
}
for(k=0;
k<
arcnum;
k++)
cout<
输入每条高速公路连接的两座城市:
v1>
v2;
i=Position(v1);
j=Position(v2);
while(i==-1||j==-1)
{
cout<
输入有误,请重新输入:
cin>
i=Position(v1);
j=Position(v2);
}
ArcNode*p=newArcNode;
p->
adjvex=j;
nextarc=vertices[i].firstarc;
vertices[i].firstarc=p;
//置对称边
ArcNode*q=newArcNode;
q->
adjvex=i;
nextarc=vertices[j].firstarc;
vertices[j].firstarc=q;
voidPrint_Road(intu,intv,intl,intd)
//求出一条长度为l的从u到v的路径
inti=0;
intm;
d++;
visited[u]=true;
path[d]=u;
if(u==v&
&
d==l){
for(i=0;
i<
l;
i++)
cout<
vertices[path[i]].data<
-->
cout<
endl;
}
elseif(u==v&
d!
=l)
{
//出现这种情况直接回溯上一顶点
gotoloop;
}
ArcNode*p=vertices[u].firstarc;
while(p)
m=p->
adjvex;
if(!
visited[m])
Print_Road(m,v,l,d);
p=p->
nextarc;
//路径长度减一
loop:
visited[u]=false;
d--;
Main.cpp
#include"
graph.h"
intmain()
GraphG;
stringcity1,city2;
intpos1,pos2;
G.Build_Graph();
//建图
cout<
请输出两座城市的名称:
cin>
city1>
city2;
pos1=G.Position(city1);
//第一所城市的位置
pos2=G.Position(city2);
//第二所城市的位置
if(pos1==-1||pos2==-1)
顶点中有不符合要求的,操作失败"
else
G.GetVexNum();
visited[i]=false;
城市"
city1<
到"
city2<
的所有简单路径如下:
for(intj=1;
j<
=G.getArcnum();
j++)
G.Print_Road(pos1,pos2,j,-1);
//输出两座城市间的所有简单路径
system("
pause>
NUL"
);
return0;