【数据结构笔记】4:非递归实现深度优先搜索(DFS)

来源:互联网 发布:js array 添加数据 编辑:程序博客网 时间:2024/06/07 15:41

图的遍历是通过此节点相邻的节点去访问其它节点,最终将整个图无重复地访问完。

对于非连通图,从一个点搜索只是搜索完这个点所在的极大连通子图,而遍历指的却是将整个图都访问完。

深度优先搜索(DFS)有点类似于树的前根序遍历,是从图的某一顶点开始搜索,被搜索过的顶点就标上已经访问的记号(由于此方法会造成无限循环,所以必须加入一个变量判断该点是否已经访问完毕),接着访问此定点的所有相邻且未被访问的一个顶点,并标上已经访问的记号,以此类推。

*递归:用系统栈实现DFS

template <class ElemType>void DFS(const AdjMatrixUndirGraph<ElemType> &g, int v, void (*Visit)(const ElemType &))// 初始条件:存在图g// 操作结果:从顶点v出发进行深度优先搜索{ElemType e;g.SetTag(v, VISITED);// 设置顶点v已访问标志g.GetElem(v, e);// 取顶点v的数据元素值 Visit(e);// 访问顶点v(的元素e)for (int w = g.FirstAdjVex(v); w != -1; w = g.NextAdjVex(v, w))//对于每个v的邻接点wif (g.GetTag(w) == UNVISITED)//如果w未被访问过DFS(g, w , Visit);// 那么从v的尚未访问过的邻接顶点w开始进行深度优先搜索}

运行结果:



*非递归:用自己创建的栈来实现DFS

#include <stack>//STL中的栈template <class ElemType>void DFS(const AdjMatrixUndirGraph<ElemType> &g, int v, void (*Visit)(const ElemType &))// 初始条件:存在图g// 操作结果:从顶点v出发进行深度优先搜索{stack<int> myStack;//STL中的栈int top;//用来记录栈顶元素索引ElemType e;//用来存元素的值myStack.push(v);//先把第一个顶点入栈while(!myStack.empty())//栈非空{top=myStack.top();//记录栈顶元素索引if(g.GetTag(top)==UNVISITED)//如果它没有被访问过,接下来就访问一下{g.SetTag(top, VISITED);//设置栈顶索引对应的元素为已访问的g.GetElem(top, e);//取栈顶索引的数据元素值Visit(e);//访问栈顶索引对应元素(的值e)}myStack.pop();//栈顶索引对应的元素访问过了就弹出来for (int w = g.FirstAdjVex(top); w != -1; w = g.NextAdjVex(top, w))//对于每个top的邻接点索引wif (g.GetTag(w) == UNVISITED)//如果索引w对应元素未被访问过myStack.push(w);//入栈}}

运行结果:


注意判断栈顶有没有被访问过是必要的,因为栈中可能会出现从不同的节点入栈的相同的元素,而这样的元素在出栈一次后就会变成VISITED了,栈里与它相同的元素就不必再重复访问了。

 

可以发现两次运行结果并不相同,这是因为在从一个节点寻找相邻的节点时,第一个方法中是找到没访问过的就立刻用DFS访问,而第二个方法中采用的是找到没访问过的就投入到栈中,这样肯定是后投入进来的先被访问。两种结果都是正确的深度优先搜索的结果。



0 0