一
无向图的深度遍历中,访问到已访问过的节点,可以得出 “存在环” 的结论;但在有向图中并不是这样。
我把我的算法详细说下,先建立一个顶点颜色表C[N]
0 白色,未被访问过的节点标白色
-1 灰色,已经被访问过一次的节点标灰色
1 黑色,当该节点的所有后代都被访问过标黑色
仍然是按图的节点深度遍历,访问到V时,V若被访问过,那么有2种状态:
C[V]=-1,程序跳出,存在环
C[V]=1,程序继续,这不是环
时间复杂度O(n+e)
参考了一下 willshy 回帖,直接试着写了一段代码实现,不知道是否考虑周全,请批评指正。
template<class NameType,class DistType>
int Graph<NameType,DistType> ::DFS(int v,int visited[])
{
//cout<<GetValue(v)<<' '; // GetValue() please add
visited[v]=-1;
int w=GetFirstNeighbor(v);
while(w!=-1)
{
if(visited[w]==0)
{
DFS(w,visited);
visited[w]=1;
}
else if (visited[w]==-1) {
cout<<"graph must be acyclic";
return 0;
}
w = GetNextNeighbor(v,w);
}
return 1;
}
二
拓扑排序
(1)在有向图中选一个没有前驱的顶点且输出之
(2)从图中删除该顶点和所有以它为尾的弧。
重复上述两步,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止,后一种情况则说明有向图中存在环。
- int TopoSort(ALGraph G)
- {
- FindInDegree(G,indegree); //对各顶点求入度
- InitStack(S);
- for(i=0;i<G.vexnum;++i)
- if(!indegree[i])Push(S,i); //入度为0者进栈
- count=0;
- while(!StackEmpty(S))
- {
- Pop(S,i);
- printf("i,G.vertices[i].da
ta"); - ++count;
- for(p=G.vertices[i].firstarc; p; p=p->nextarc)
- {
- k=p->adjvex;
- if(!(--indegree[k]))Push(S,k); //若入度减为0,则入栈
- }
- }
- if(count<G.vexnum)return 0; //该有向图存在环
- else
- return 1;
- }