深度优先搜索(dfs)
这几天在看深度优先搜索,把自己理解的深度的内容给整理一下。
深度优先搜索,其实就是个回溯法,沿着图中的某一个点,找到它的一个邻接点,然后在找该点的邻接点,一直这样的持续下去,就是按照一条路子走到底,直到最后那个节点没有邻接点,或者说它的邻接点都被访问过了,然后我们就退回来,到上一步,找它父节点的另一个邻接点,然后沿着该点在继续的走下去,如果又走完了,就再返回上一次,这样就一直的返回,直到开始那个点的,其中一个邻接点对应的那条路上的点都走完了,ok,在找起始点的另一个邻接点,继续走下去,就这样走到底,走完之后再往上回溯,到原点。
说到底呢,就是个回溯法,沿着一个邻接点走到底,直到无路可走,然后往上回溯,找另外一个邻接点。
一句话,dfs就是沿着木一个邻接点一条路走到底,走完之后回来再走另外的一个临界的点,最后把该点的所有邻接点都走完就是最终的目标。
按照上面的思路写个递归算法是很简单的。
1.递归算法
//初始化数组都为false
visit[]=false;
//DFS递归算法
void DFS(Graphics G,int v){
//1.对于当前该点,进来就把visit设为true,然后visit之
visit[i]=true;//访问之
visit(i);//调用的函数,对该点的操作
//2.然后开始找到该点的其中一个邻接点,如果没有被访问那么就对该点递归调用DFS
对该点递归调用完了之后要找到它的第二个邻接点(如果有的话),然后对第二个邻接点递归调用DFS,依次类推,如果有第三个的话,那么就第三个。
//用循环来实现那个找临界点并且递归调用的过程。
for(w=FirstAdjvex(G,v)w>=0;NextAdjvex(G,v,w)){
if(!visit[w])DFS(G,v);
}
}
2.用栈来实现更能清楚的理解每一个过程是如何的 。
//1.初始化工作,包括栈的初始化,以及数组的初始化(略)
//2.找到第一个节点,访问之并且入栈。
visit[i]=true;
visit(i);
push(s,i);//将该节点入栈
//3.当栈不空的时候,就找到栈顶的元素,如果栈顶元素所有的邻接点都访问过了,则将栈顶元素删去,否则把它的其中一个未访问过的邻接点入栈。
while(!empty(s)){
i=getop(s);//得到栈顶元素
//查找以i为节点的邻接点是否被访问,如果有未被访问的,则入栈。
j=0;
while(j<G.vexnum){
if(G.vex[i][j]==1&&!visit[j]){
visit[j]=true;
visit(j);
push(s,j);
break;//此处很重要,不是把该点所有未访问的邻接点都在此时入栈,而是找到一个就入栈,然后就不找当前的点的邻接点啦。
}
else j++;
}
//如果循环最后结束的时候,没有找到该点的邻接点,就把当前的点退栈。
if(j==G.vexnum)pop(i);
}
就如上图所示,1,2,5,8,9,6,7,3,4
1258就是第一次一次到底的过程,8的邻接点都访问过了,然后回溯,到5,找5的邻接点9未访问,访问,然后9到头了,回溯到5,5也访问完了,回溯到2,2的6,访问,回溯到2,访问7,回溯到2,2访问完了,回溯到1,访问3,回溯到1,访问4。
1
12
125
1258
1259
126
127
13
14
1
空
上面依次是栈中情况。