您的位置:首页 > 编程语言 > C语言/C++

对有向图的环的判定,并且输出图中所有的路径 C++算法

2015-09-11 18:16 519 查看
说明:我们选择的图是有向图,图的存储方式是邻接矩阵,使用C++语言,基于vs2010平台

算法思想:逐个对图中的出度不为0的点进行遍历。假如是先对图A节点进行遍历:首先,将A节点所连接的点存储在数组vect1中,然后对A节点进栈,并对A节点的连接点进行深度优先。当节点的出度为0时,出栈,出栈的时候判断该节点是不是在vec1中的元素,如果是则为环,若不是则不是环。

代码:

#include<iostream>
#include<vector>
#include<fstream>
using namespace std;

#define N  6
int Mgraph

={    //邻接矩阵
{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[]
,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[]
,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中,若在则是环,若不在则不是环。

结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: