邻接矩阵实现--图的深度优先遍历DFS和广度优先遍历BFS

来源:互联网 发布:ubuntu java环境搭配 编辑:程序博客网 时间:2024/04/28 09:44

          图论中一个基本的概念就是遍历。就是访问到图的每一个顶点,同时每个顶点只访问一次。

          DFS和BFS的概念和思路网上说明的很详细了。但是网上很多代码实现有缺陷,基本都没有考虑图不连通的情况,比如某个顶点A和其它任何一个顶点都不关联,那么这个顶点A就访问不到了。如果遍历的起点刚好是孤立的顶点A,就只能访问顶点A了,其它顶点就访问不到了。

          我这边的代码就是增加了这些情况的处理,确保每个顶点都能可以访问到。

          完整的代码如下(通过邻接矩阵实现图):

#define MAX_VERTEX 16typedef enum{UNDIRECTED_GRAPH = 0, //无向图DIRECTED_GRAPH = 1, //有向图UNDIRECTED_NET = 2, //无向网DIRECTED_NET = 3, //有向网}GRAPH_TYPE;typedef struct{GRAPH_TYPE type; //图的类型int vertexCount;//顶点个数BOOL visitFlag[MAX_VERTEX];char vertex[MAX_VERTEX]; //顶点数组int edge[MAX_VERTEX][MAX_VERTEX]; //邻接矩阵}GRAPH,*PGRAPH;void Visit(PGRAPH graph,int vIndex){graph->visitFlag[vIndex] = TRUE; //设置已访问标志printf("Visit Vertex: %c\r\n",graph->vertex[vIndex]);}void DFS(PGRAPH graph,int startVertexIndex){stack<int> s; //访问栈s.push(startVertexIndex);while(!s.empty()){int vertexIndex = s.top();if(!graph->visitFlag[vertexIndex])//未访问过{Visit(graph,vertexIndex);}s.pop();//vertexIndex顶点出栈for(int j=graph->vertexCount-1;j>=0;j--){if(!graph->visitFlag[j] && graph->edge[vertexIndex][j]){s.push(j); //于vertexIndex相邻的顶点并且未访问过的顶点全部入栈}}}//图并不一定是连通的,因此要确保每个顶点都遍历过for(int i=0;i<graph->vertexCount;i++){if(!graph->visitFlag[i]){printf("Not Connected vertex start DFS: %c\r\n",graph->vertex[i]);DFS(graph,i);}}}void BFS(PGRAPH graph,int startVertexIndex){queue<int> q; //访问队列q.push(startVertexIndex);//起始访问的顶点入队while(!q.empty()){int vertexIndex = q.front();if(!graph->visitFlag[vertexIndex])//未访问过{Visit(graph,vertexIndex);}q.pop();//vertexIndex顶点出队for(int j=0;j<graph->vertexCount;j++){if(!graph->visitFlag[j] && graph->edge[vertexIndex][j]){q.push(j); //于vertexIndex相邻的顶点并且未访问过的顶点全部入队}}}//图并不一定是连通的,因此要确保每个顶点都遍历过for(int i=0;i<graph->vertexCount;i++){if(!graph->visitFlag[i]){printf("Not Connected vertex start BFS: %c\r\n",graph->vertex[i]);BFS(graph,i);}}}void InitGraph(PGRAPH graph){graph->type = UNDIRECTED_GRAPH; //无向图graph->vertexCount = 10;for(int i=0;i<graph->vertexCount;i++){graph->vertex[i] = 'A'+i; //顶点为'A','B','C'等等}graph->edge[0][1] = 1;//AB有边graph->edge[1][0] = 1;graph->edge[0][4] = 1;//AE有边graph->edge[4][0] = 1;graph->edge[1][3] = 1;//BD有边graph->edge[3][1] = 1;graph->edge[2][4] = 1;//EC有边graph->edge[4][2] = 1;graph->edge[2][5] = 1;//CF CG CH 有边graph->edge[5][2] = 1;graph->edge[2][6] = 1;graph->edge[6][2] = 1;graph->edge[2][7] = 1;graph->edge[7][2] = 1;graph->edge[6][8] = 1;//GI GJ 有边graph->edge[8][6] = 1;graph->edge[6][9] = 1;graph->edge[9][6] = 1;}void InitVistFlag(PGRAPH graph){for(int i=0;i<graph->vertexCount;i++){graph->visitFlag[i] = FALSE;}}void TestGraph(){GRAPH graph = {UNDIRECTED_GRAPH,0};InitGraph(&graph);printf("Test BFS,Start vertex 0:\r\n");BFS(&graph,0);InitVistFlag(&graph);printf("\r\nTest DFS,Start vertex 0:\r\n");DFS(&graph,0);InitVistFlag(&graph);for(int i=0;i<graph.vertexCount;i++){graph.edge[2][i] = 0;graph.edge[i][2] = 0;//使得第3个顶点和任何顶点都不连通}printf("\r\nTest BFS,Start vertex 5:\r\n");BFS(&graph,5);InitVistFlag(&graph);printf("\r\nTest DFS,Start vertex 5:\r\n");DFS(&graph,5);}

阅读全文
0 0