说明:我们选择的图是有向图,图的存储方式是邻接矩阵,使用C++语言,基于vs2010平台
算法思想:逐个对图中的出度不为0的点进行遍历。假如是先对图A节点进行遍历:首先,将A节点所连接的点存储在数组vect1中,然后对A节点进栈,并对A节点的连接点进行深度优先。当节点的出度为0时,出栈,出栈的时候判断该节点是不是在vec1中的元素,如果是则为环,若不是则不是环。
代码:
#include<iostream>
#include<vector>
#include<fstream>
using namespace std;
#define N 6
int Mgraph[N][N]={ //邻接矩阵
{0,1,0,1,0,0},
{0,0,1,1,1,0},
{0,0,0,0,0,0},
{0,0,1,0,0,0},
{0,0,0,0,0,0},
{0,0,0,0,0,0}
};
void turn_graph(int Mgraph[][N],vector<vector<int> >&i_graph)
{
vector<int>temp;
int i,j;
for(i=0;i<N;++i)
{
temp.clear();
for(j=0;j<N;++j)
temp.push_back(Mgraph[i][j]);
i_graph.push_back(temp);
}
}
void show_graph(vector<vector<int> >i_graph)
{
int i,j;
cout<<"i_graph元素是:"<<endl;
for(i=0;i<i_graph.size();++i)
{
for(j=0;j<i_graph[i].size();++j)
cout<<i_graph[i][j]<<" ";
cout<<endl;
}
}
//void search(int Mgraph[][N],int x) //在邻接矩阵中搜索从点x开始的路径
void search(vector<vector<int> >i_graph,int x)
{
int i;
int size=i_graph.size();
vector<int> compare; //存储点x通向的点
vector<int> visit;
vector<int> stack;
int top=-1;
compare.clear();
for(int k1=0;k1<size;++k1)
{
compare.push_back(0);
}
for( i=0;i<size;++i)
{
if(i_graph[x][i]==1) //将点x通向的点,存储到compare中
compare[i]=1;
}
for( i=0;i<size;++i) //对点x的每个点进行遍历
{
//初始化
visit.clear();
stack.clear();
for(int k1=0;k1<size;++k1)
{
visit.push_back(0);
stack.push_back(0);
}
top=-1;
// stack.push_back(x);
stack[++top]=x;
visit[x]=1;
if(i_graph[x][i]==1) //若有连接
{
stack[++top]=i;
visit[i]=1;
while(top!=0) //根节点x不应该出栈
{
int k1;
i=stack[top];
for( k1=0;k1<size;++k1)
{
if(i_graph[i][k1]==1&&!visit[k1])
{
stack[++top]=k1;
visit[k1]=1;
break;
}
}
if(k1==size) //若没有与其它节点相连的,就输出stack中所有的元素
{
if(top>1)
{
for(int k2=0;k2<=top;++k2)
{
cout<<stack[k2];
}
if(compare[stack[top]]==1)
cout<<" 环"<<endl;
else
cout<<endl;
}
--top;
}
}
}
}
}
void main()
{
vector<vector<int> >i_graph;
int i=1;
turn_graph(Mgraph,i_graph); //将邻接矩阵转移到vector存储的i_graph中
// show_graph(i_graph);
cout<<"图中的环以及路径为:"<<endl;
for(int i=0;i<N;++i)
{
search(i_graph,i);
}
}
由于条件的原因,我需要把数组转换成vector的格式,当然若是提前知道节点数目,用数组会更方便一些。
main函数中,使用一个for循环逐个遍历节点(当节点数目比较多时,为了提高效率,最好只遍历那些有出度的点)。search(i_graph,i)函数在数组中寻找以节点开始的环。
在search(i_graph,i)函数中,先把i所连接的点存储在compare中用于之后判断是不是环。然后对与i相连接的点遍历,先把根节点i进栈,然后使用深度遍历,但是根节点i不出栈。当遍历的节点没有出度时,将栈中除根节点的节点出栈,并且判断top节点是否在compare中,若在则是环,若不在则不是环。
结果: