邻接矩阵的深度优先遍历
对《大话数据结构》P240——邻接矩阵的深度优先遍历,进行了自己的理解并完善了代码。
邻接表的深度优先遍历见http://www.cnblogs.com/hslzju/p/5399832.html
举个简单的无序图例子,为了节省时间传手稿。
首先用邻接矩阵的存储结构创建该图,再进行深度优先遍历。
代码和解释如下(VS2012测试通过):
1 #include <iostream>
2 #include <stdlib.h>
3 using namespace std;
4
5 typedef struct//图的邻接矩阵存储结构
6 {
7 char vexs[5];
8 int arc[5][5];
9 int numVertexes,numEdges;
10 }MGraph;
11
12 MGraph *CreateMGraph(MGraph *G)//图的创建
13 {
14 G=(MGraph*)malloc(sizeof(MGraph));
15 int i,j,k;
16 cout<<"input numVertexes and numEdges"<<endl;
17 cin>>G->numVertexes>>G->numEdges;//输入5 8
18 cout<<"input numVertexes"<<endl;
19 for(i=0;i<G->numVertexes;i++)
20 cin>>G->vexs[i];//每次循环依次输入A B C D E
21 for(i=0;i<G->numVertexes;i++)
22 for(j=0;j<G->numVertexes;j++)
23 G->arc[i][j]=0;
24 for(k=0;k<G->numEdges;k++)
25 {
26 cout<<"input vi and vj"<<endl;
27 cin>>i>>j;//每次循环依次输入0 1,0 2,0 3,0 4,1 2,1 4,2 3,3 4
28 G->arc[i][j]=1;
29 G->arc[j][i]=1;
30 }
31 return G;
32 }
33
34 int visited[5];//设置为全局变量,DFS和DFSTraverse函数都有用到
35
36 //以下标为i的顶点vexs[i]开始访问,进行一次深度优先递归,对连通图,可以访问到所有的顶点
37 void DFS(MGraph *G,int i)
38 {
39 visited[i]=1;//访问过的顶点标记为1
40 cout<<G->vexs[i]<<" ";//递归之前需要打印当前访问的顶点
41 for(int j=0;j<G->numVertexes;j++)//从第0个顶点开始判断,直到最后一个顶点
42 if((G->arc[i][j]==1)&&(!visited[j]))//若顶点vexs[j]与顶点vexs[i]相连,并且vexs[j]没有访问过
43 DFS(G,j);//那就访问vexs[j]
44 //cout<<G->vexs[i]<<" ";//如果写在最后,则逆序输出,可以将上面的cout注释掉试一下
45 }
46
47 //邻接矩阵的深度遍历
48 void DFSTraverse(MGraph *G)
49 {
50 for(int i=0;i<G->numVertexes;i++)
51 visited[i]=0;//初始化所有顶点都是未访问过
52 for(int i=0;i<G->numVertexes;i++)
53 if(!visited[i]) DFS(G,i);
54 //从vexs[0]开始进行深度优先递归,若是连通图,只会执行一次DFS(G,0)
55 //因为深度优先递归后每个visited[i]都是1,不会再执行if了
56 //若是非连通图,可能会执行到DFS(G,1),DFS(G,2),DFS(G,3),DFS(G,4)
57 }
58
59 int main()
60 {
61 MGraph *p=NULL;
62 p=CreateMGraph(p);//这里也可以用二级指针,参考二叉树为什么用二级指针作为参数那篇博客
63 cout<<p->vexs[0]<<" "<<p->vexs[1]<<" "<<p->vexs[2]<<" "<<p->vexs[3]<<" "<<p->vexs[4]<<endl;
64 cout<<p->arc[0][1]<<" "<<p->arc[0][2]<<" "<<p->arc[0][3]<<" "<<p->arc[0][4]<<" "<<p->arc[1][2]<<" "<<p->arc[1][4]<<" "<<p->arc[2][3]<<" "<<p->arc[3][4]<<endl;
65 //验证创建是否正确
66 //DFS(p,2);//举个例子,若从下标2开始,执行一次DFS(G,2),输出的遍历顺序是CABED
67 DFSTraverse(p);//输出的遍历顺序是ABCDE
68 }
1、先理解void DFS(MGraph *G,int i)这个函数,假设从下标2开始,执行一次DFS(G,2),那么遍历结果是CABED
main函数中用DFS(p,2);把DFSTraverse(p);注释掉。
由于是连通图,执行一次DFS(G,2)即可遍历全部顶点。
2、考虑问题得全面,如果是非连通图,执行一次DFS(G,2),会有顶点没有被遍历到。解决办法是依次执行DFS(G,0),DFS(G,1),DFS(G,2),DFS(G,3),DFS(G,4)即可。用visited[i]对是否访问过该顶点标记,防止不必要的循环。
main函数中用DFSTraverse(p);把DFS(p,2);注释掉。
-------------------------------------------------
原创博客 转载请注明出处http://www.cnblogs.com/hslzju
-------------------------------------------------
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步