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

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

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

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

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

#define MAX_VERTEX 16

typedef 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);
}

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/faithzzf/article/details/78055538
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞