图的深度遍历(Depth First Serch),即DFS。采用递归方法。如果当前顶点有一下层节点则没有被访问过,则访问,否则回溯。
下面动画,展示了DFS算法的具体过程。
代码如下
//TestMGraph.cpp #include "MatrixGraph.h" #define DefA 0 #define DefB 1 #define DefC 2 #define DefD 3 #define DefE 4 #define DefF 5 #define DefG 6 #define DefH 7 #define DefI 8 void CreateGraph1(MatrixGraph & mGraph) { std::vector<char> vertexName; char arr[]={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'}; vertexName.insert(vertexName.begin(), arr, arr+9); std::vector<Edge> edges; Edge e; //1 e.weight = 1; e.i = DefA;e.j=DefB; edges.push_back(e); //2 e.i = DefF;e.j=DefE; edges.push_back(e); //3 e.i = DefC;e.j=DefD; edges.push_back(e); //4 e.i = DefI;e.j=DefD; edges.push_back(e); //5 e.i = DefA;e.j=DefF; edges.push_back(e); //6 e.i = DefB;e.j=DefG; edges.push_back(e); //7 e.i = DefB;e.j=DefC; edges.push_back(e); //8 e.i = DefD;e.j=DefE; edges.push_back(e); //9 e.i = DefG;e.j=DefD; edges.push_back(e); //10 e.i = DefG;e.j=DefF; edges.push_back(e); //11 e.i = DefB;e.j=DefI; edges.push_back(e); //12 e.i = DefG;e.j=DefH; edges.push_back(e); //13 e.i = DefH;e.j=DefD; edges.push_back(e); //14 e.i = DefH;e.j=DefE; edges.push_back(e); // e.i = DefC;e.j=DefI; edges.push_back(e); CreateMatrixGraph(mGraph, vertexName, edges); } void TestMGraph() { MatrixGraph mGraph; CreateGraph1(mGraph); MDFSTraverse(mGraph, 0); //MBFSTraverse(mGraph, 0); }
//MatrixGraph.h #pragma once #include <vector> struct MatrixGraph { enum{MAXVEX=100}; static const int INFINITY; char vexs[MAXVEX]; //顶点类型 char int arc[MAXVEX][MAXVEX]; //邻接矩阵 int numVerteices; //图中当前的顶点数 int numEdges; //图中当前的边数 MatrixGraph(); }; void CreateMatrixGraph(MatrixGraph & mGraph, std::vector<char> & vertexName, std::vector<Edge> & edges); void MDFSTraverse(MatrixGraph & mGraph, int v);
//MatrixGraph.cpp #include "MatrixGraph.h" #include <iostream> #include <memory.h> #include <queue> const int MatrixGraph::INFINITY = INT_MAX; bool visited[MatrixGraph::MAXVEX]; MatrixGraph::MatrixGraph() :numVerteices(0), numEdges(0) { //temp memset(vexs, 0, sizeof(char)*MAXVEX); for(int i=0; i<MAXVEX; i++) { for(int j=0; j<MAXVEX; j++) { arc[i][j] = INFINITY; } } for(int i=0; i<MAXVEX; i++) { arc[i][i] = 0; } } void CreateMatrixGraph(MatrixGraph & mGraph, std::vector<char> & vertexName, std::vector<Edge> & edges) { int count = vertexName.size(); mGraph.numVerteices = count; //生成顶点 for(int i=0; i<count; i++) { mGraph.vexs[i] = vertexName[i]; //i为顶点的编号 } //生成边 count = edges.size(); //一定是偶数 for(int k=0;k<count; k++) { mGraph.arc[edges[k].i][edges[k].j] = mGraph.arc[edges[k].j][edges[k].i] = edges[k].weight; //无向图 } } //返回v节点的第一个邻接顶点。若顶点v在图中没有邻接顶点,则返回-1 int FirstAdjVex(MatrixGraph & mGraph, int v) { for(int j=0; j<mGraph.numVerteices; j++) { //图的边有权重 不相连的边的权重为INFINITY 权重为非负整数 if(mGraph.arc[v][j] != MatrixGraph::INFINITY && mGraph.arc[v][j] != 0 && !visited[j]) //if(mGraph.arc[v][j] != MatrixGraph::INFINITY && mGraph.arc[v][j] != 0) return j; } return -1; } //返回v的(相对于w的)下一个邻接顶点。若访问完了v的所有顶点,则返回-1 int NextAdjVex(MatrixGraph & mGraph, int v, int w) { for(int j=w; j<mGraph.numVerteices; j++) { //图的边有权重 不相连的边的权重为INFINITY 权重为非负整数 if(mGraph.arc[v][j] != MatrixGraph::INFINITY&& !visited[j]) //if(mGraph.arc[v][j] != MatrixGraph::INFINITY) { return j; } } return -1; } //《结构结构》(c语言版) 严蔚敏 void MDFS(MatrixGraph & mGraph, int v, int parentID) { //从第v个顶点出发递归深度优先遍历图G visited[v] = true; std::cout<<mGraph.vexs[v] <<":parent="<<mGraph.vexs[parentID]<<std::endl; for(int w = FirstAdjVex(mGraph, v); w>-1; w=NextAdjVex(mGraph, v, w)) { if(!visited[w]) MDFS(mGraph, w, v); //对v的沿未访问的邻接顶点w递归调用DFS } } void MDFSTraverse(MatrixGraph & mGraph, int v) { memset(visited, 0, sizeof(bool)*MatrixGraph::MAXVEX); MDFS(mGraph, v, 0); }
结果
A:parent=A B:parent=A C:parent=B D:parent=C E:parent=D F:parent=E G:parent=F H:parent=G I:parent=D 请按任意键继续. . .
随便说一下,代码结构参考《数据结构》(c语言版) 严蔚敏【1】。但【1】中的代码不能从任意一个顶点开始深度遍历。且【1】中的代码可以遍历非连通图,并不是专门为遍历连通图设计的。
给CSDN提个建议:通过CSDN博客上传GIF图片,插入博客中。GIF图片是死图。建议修改成活图。