图的深度优先搜索的非递归版本算法的两种实现

                            图的深度优先搜索的非递归版本算法的两种实现

       Two unrecursive implementation of the deep first graph search algorithm

EmilMatthew  (EmilMatthew@126.com)

 

摘要:

图的深度优先算法的递归版本相当简洁好懂。将递归版本的算法改写成非递归版本的难度并不大,关键是要处理好如何正确的在搜索的过程中存储搜索树中的子结点,并正确的进行访问.一种实现采用了两个栈,而另一种则使用一个结点类型为队列的栈..

 

Abstract

The recursive version of the deep first graph search algorithm is very concise to be understood. It is not a difficult job to change the recursive version into unrecursive version, the key technique in the algorithm transformation is to make and visit the child node during the search processing ,which should be handled in a correctly and precise way. One implementation use two stacks while the other version use a stack which has the node of queue type.

 

       关键词:图的搜索,非递归,深度优先

 

1图的深度优先搜索算法的回顾:

图的深度优先搜索用递归实相当的简洁好懂:

void dftR(PGraphMatrix inGraph)

{

       PVexType v;

      

       assertF(inGraph!=NULL,"in dftR, pass in inGraph is null/n");

      

       printf("/n===start of dft recursive version===/n");

       for(v=firstVertex(inGraph);v!=NULL;v=nextVertex(inGraph,v))

              if(v->marked==0)

                     dfsR(inGraph,v);

       printf("/n===end of   dft recursive version===/n");

}

 

void dfsR(PGraphMatrix inGraph,PVexType inV)

{

       PVexType v1;

      

       assertF(inGraph!=NULL,"in dfsR,inGraph is null/n");

       assertF(inV!=NULL,"in dfsR,inV is null/n");

      

       inV->marked=1;

       visit(inV);

      

       for(v1=firstAdjacent(inGraph,inV);v1!=NULL;v1=nextAdjacent(inGraph,inV,v1))

              if(v1->marked==0)

                     dfsR(inGraph,v1);

}

       2非递归版本

2.1.1非递归版本1---借助结点类型为队列的栈实现

       首先,将从某个顶点开始进行的深度优先搜索树画出,可以看到,对从某个结点开始的深度优先遍历,实际上就是基于这个深度优先搜索树一个遍历,不过,树中的的很多结点当marked值为1时将不必再访问.

       举例如下:

      

 

 

   

       根据深度优先搜索规则,图1对应的两棵深度优先搜索树如右所示.

       其中,用土黄色”//”标注的树枝表示在第一次试探的过程中便不需要访问的边,而用蓝色”//”标注的树枝则表示在回访过程中不再需要访问的结点.

      

       联系树的前序遍历的非递归实现:

       可知,其中无非是分成“探左”和“访右”两大块访右需借助栈中弹出的结点进行.

       在图的深度优先搜索中,同样可分成“深度探索”和“回访上层未访结点”两块:

       1图的深度探索这样一个过程和树的“探左”完全一致,只要对已访问过的结点作一个判定即可.

       2而图的回访上层未访结点和树的前序遍历中的“访右”也是一致的.但是,对于树而言,是提供rightSibling这样的操作的,因而访右相当好实现。在这里,若要实现相应的功能,我考虑是将每一个当前结点的下层结点中,如果有m个未访问结点,则最左的一个需要访问,而将剩余的m-1个结点按从左到右的顺序推入一个队列中。并将这个队列压入一个堆栈中。

       这样,当当前的结点的邻接点均已访问或无邻接点需要回访时,则从栈顶的队列结点中弹出队列元素,将队列中的结点元素依次出队,若已访问,则继续出队(当当前队列结点已空时,则继续出栈,弹出下一个栈顶的队列),直至遇到有未访问结点(访问并置当前点为该点)或直到栈为空(则当前的深度优先搜索树停止搜索)

      

将算法通过精简过的C源程序的方式描述如下:

       /*dfsUR:功能从一个树的某个结点inV

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值