求顶点间所有简单路径 实验
1.1 实验内容
一个图,给定两个顶点,(1) 判断两个顶点间是否存在路径;(2) 求该两个顶点间的所有简单路径。
1.2 实验思路
一个图,给定两个顶点,(1) 判断两个顶点间是否存在路径;(2) 求该两个顶点间的所有简单路径。
1.3文件结构、开发环境等说明
开发环境版本 |
VisualStudio 2022 |
工程文件名 |
ex2_1 isconnect.sln |
头文件个数 |
5个 |
源程序文件个数 |
1个 |
文件类型 |
功能简介 |
备注 | |
AdjListDirNetwork.h |
头文件 |
邻接表类模板头文件,包括数据成员及成员函数的声明与定义 | |
AdjListDirNetworkArc.h |
头文件 |
邻接表边结点类模板头文件,包括数据成员及成员函数的声明与定义 | |
AdjListDirNetworkVec.h |
头文件 |
邻接表顶点结点类模板头文件,包括数据成员及成员函数的声明与定义 | |
stack.h |
头文件 |
栈结构体的定义以及部分函数的定义 | |
Assistance.h |
头文件 |
辅助软件包 | |
text.cpp |
源文件 |
测试文件 |
1.4 实现技术
1、邻接表表示图
通过三个头文件“AdjListDirNetwork.h”、“AdjListDirNetworkArc.h”、“AdjListDirNetworkVec.h”,用邻接表类、邻接表边结点类、邻接表顶点结点类将图用邻接表的存储结构表示(这里不展示相关代码)。
2、用DFS与栈查找并存储所有简单路径
在邻接表类中声明并定义成员函数DFS。
template <class ElemType, class WeightType>
void AdjListDirNetwork<ElemType, WeightType>::DFS(int v, int u, Stack* s)
{
push(s, v);
if (u == v) {
show(s);
pop(s);
return;
}
for (int i = this->FirstAdjVex(v); i != -1; i = this->NextAdjVex(v, i))
{
if (check(s, i) && i != u)
continue;
DFS(i, u, s);
}
pop(s);
}
先将起始顶点v利用push()函数放入栈s中(在此之前已经完成了栈的初始化),反复多次调用该函数就能把从v到u上所有经过的顶点通过++s->top完成存储。
void push(Stack* s, int v)
{
if (s->top == 9)
return;
s->num[++s->top] = v;
}
通过for循环并递归调用DFS()函数找到从v到u上经过的一条路径上的所有顶点。调用邻接表类中的FirstAdjVex()函数,将v的第一个邻接点赋给i,并调用check()函数判断i是否在栈s中。
int check(Stack* s, int v)
{
for (int i = 0; i <= s->top; i++)
{
if (v == s->num[i])
return 1;
}
return 0;
}
如果在,利用continue跳过下面的DFS函数,如果不在则再次调用DFS函数,将该顶点i放入栈s中,直到u和v(即i)相等,这时已经到了终点,调用show()函数将栈内数据(也就是路径)输出。
void show(Stack* s)
{
int m = s->top;
int a = 0;
while (a <= m)
{
if (a < m)
cout << s->num[a] << "-->";
else
cout << s->num[a] << endl;
a++;
}
}
再调用pop()函数,移除栈顶元素,并开始下一条从v到u的简单路径的寻找与存储。
int pop(Stack* s)
{
if (s->top == -1)
return 0;
else
return s->num[s->top--];
}
3、测试
将图的相关信息输入到vexs[]和m[][]中,再将邻接表类模板实例化生成模板类net,再将信息存储到该类中。调用init()函数初始化栈,再调用net类中的成员函数DFS(),正式开始进行顶点a、b之间所有简单路径的查找与输出。
1.5测试情况
1、测试实例
2、邻接表表示有向网
3、顶点a和b之间的所有简单路径
(1) 顶点0和5之间的所有简单路径
(2) 顶点1和4之间的所有简单路径
(3) 顶点2和4之间的所有简单路径
完整代码可看资源区
创作不易~麻烦点个赞~~谢谢大家~~~