寻路问题
在图上如何寻找从1到8的路径
一种策略:只要能发现没走过的点,就走到它。有多个点可走就随便挑一个,如果无路可走就回退,再看看有没有走过的点可走
在图上如何寻找从1到8的路径
运气最好:1->2->4->8
运气稍差:1->2->4->5->6->8
运气坏:1->3->7->9=>7->A=>7=>3->5->6->8(双向箭头表示回退)
不连通的图,无法从结点1走到结点8
完整的尝试过程可能如下
1->2->4->3->7=>3=>4=>2->9=>2=>1
结论:不存在从1到8的路径
得出这个结论之前,一定会把从1出发能走到的点全部走过。
(在走的过程中,我们需要记住某一点已经被走过)
从起点出发,走过的点要做标记,发现有没走过的点,就随意挑一个往前走,走不了就回退,此种路径搜索策略就被称为深度优先搜索,简称深搜
其实称为远度优先搜索更容易理解一些,因为这种搜索策略能往前走一步就往前走一步,总是试图走的更远,所谓远近(或深度),就是以距离起点的步数来衡量的。
在图上寻找路径
int main(){
将所有点都标记为新店;
起点=1
终点=8
cout<<dfs(起点);
}
//判断从V出发能否走到终点
bool dfs(v){
if(v为终点)
return true;
if(v为旧点)
return false;
将v标记为旧点
对和v相邻的每个结点U{
if(dfs(U)==true){
return true;
}
}
return false;
}
判断从V出发是否能够走到终点,如果能,要记录路径
Node path[MAX_LEN]; //MAX_LEN取结点总数即可
int depth; //从起点走到它,走的深度,起点深度为0
//从起点出发,寻找到终点的路径, 并且在这过程中,要把走过的路径给记下来
bool dfs(V){
if(V为终点){
path[depth]=v; //记录到路径中去
return true;
}
if(V为旧点)
return false;
将v标记为旧点;
path[depth]=v; //没有走,就走这个点
++depth;
对和v相邻的每个结点U{
if(dfs(U)==true){ //从u出发能不能到达终点
return true;
}
//如果把和v相邻的每个顶点都试过了也无法走到终点,v就不应该出现在从起点到终点的路径上面。相当于回退,退到v的父节点上面
--depth;
return false;
}
}
int main(){
将所有点都标记为新点;
depth=0;
//从起点到终点找路,如果找到了路,还得把路记下来,如果起点返回值为true,//说明我们已经找到了从起点到终点的路,并且这条路已经被记录在path数组
//里面了,这条路上面的结点数是由depth来记录的
if(dfs(起点)){
for(int i=0;i<=depth;++i){
cout<<path[i]<<endl;
}
}
}
1->3->7->9=>7->A=>7=>3->5->6->8
分析过程:走1379,回退到7,把9给弹出去,走到A,又把A放进去了。然后回退到7,把A弹出去了,然后回退到3,把7弹出去了,然后从3走到5,把5放到path中,然后走到6,6被放到path中,然后再走到8,8被放到path中去了。此时就可以找到路径
path:1,3,5,6,8
遍历图上所有结点
dfs(v){
if(v是旧点){
return;
}
将v标记为旧点;
对和v相邻的每个点U{
dfs(U);
}
}
int main(){
将所有点都标记为新点;
while(在图中能找到新点k)
dfs(k);
}