对有向图的环的判定,并且输出图中所有的路径 C++算法
2015-09-11 18:16
519 查看
说明:我们选择的图是有向图,图的存储方式是邻接矩阵,使用C++语言,基于vs2010平台
算法思想:逐个对图中的出度不为0的点进行遍历。假如是先对图A节点进行遍历:首先,将A节点所连接的点存储在数组vect1中,然后对A节点进栈,并对A节点的连接点进行深度优先。当节点的出度为0时,出栈,出栈的时候判断该节点是不是在vec1中的元素,如果是则为环,若不是则不是环。
代码:
由于条件的原因,我需要把数组转换成vector的格式,当然若是提前知道节点数目,用数组会更方便一些。
main函数中,使用一个for循环逐个遍历节点(当节点数目比较多时,为了提高效率,最好只遍历那些有出度的点)。search(i_graph,i)函数在数组中寻找以节点开始的环。
在search(i_graph,i)函数中,先把i所连接的点存储在compare中用于之后判断是不是环。然后对与i相连接的点遍历,先把根节点i进栈,然后使用深度遍历,但是根节点i不出栈。当遍历的节点没有出度时,将栈中除根节点的节点出栈,并且判断top节点是否在compare中,若在则是环,若不在则不是环。
结果:
算法思想:逐个对图中的出度不为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中,若在则是环,若不在则不是环。
结果:
相关文章推荐
- C++ Regsvr32订购具体解释
- 【C++基金会 06】explictkeyword
- 排序算法总结(C++)
- C++编程笔记 一(函数重载与运算符重载)
- 关于C++编译静态模板成员数据出错 Too few template-parameter-lists
- c++中输入与输出流
- C语言中函数参数入栈的顺序
- c#调用c++的回调函数
- c++ --> cin和cout输入输出格式
- C++ 文件读取
- C语言scanf函数详细解释
- 黑马程序员-----------C语言基础-----------C语言(理论)
- C语言将文件读入内存
- c++模板类学习
- 黑马程序员-----------C语言基础-----------预处理指令
- c语言的错误及警告对照表———— 在遇到时可以对照查看
- 【C++】返回单链表的第k个结点
- C++之多态性与虚函数
- 黑马程序员-----------C语言基础-----------结构体·枚举
- STL List容器详解