图论(四) 图的遍历 【DFS、BFS】

图建构好后,针对具体的问题,我们常常需要通盘的读取图中的信息,包括顶点( v e r t e x vertex vertex)和边( e d g e edge edge),以及它们之间的关系。这种读取图中所有信息的方法就是图的遍历( t r a v e r s a l traversal traversal),也称为搜索( s e a r c h search search),就是从图中某个顶点出发,沿着一些边访问图中所有的顶点,且使每个顶点仅被访问一次。遍历是很多图论算法的基础。

常用的图的遍历方法有 D F S DFS DFS( d e p t h depth depth f i r s t first first s e a r c h search search)与 B F S BFS BFS( b r e a d t h breadth breadth f i r s t first first s e a r c h search search)

DFS(深度优先遍历)

深度优先遍历( D e p t h Depth Depth F i r s t First First S e a r c h Search Search),也被称为深度优先搜索,简称 D F S DFS DFS

简单来说,就好比在房间中寻找钥匙,这个时候有很多种寻找方案,而我们采用 D F S DFS DFS的思想,就无论从哪个房间开始寻找都可以,比如主卧室,然后从房间中的每一个角开始,将房间内的墙角、床头柜、床上、床下等挨个寻找,做到不放过任何一个角落,等每个角落都寻找完后,再寻找下一间,直到找到为止

邻接矩阵实现

typedef char VextexType;  //顶点类型(自定义)
typedef int EdgeType;    //边上权值类型(自定义)
#define MAXVEX 100      //最大顶点数
#define INFINITY 65535  //代替 无穷
typedef struct {
	VextexType vexs[MAXVEX];  //顶点表
	EdgeType arc[MAXVEX][MAXVEX];  //邻接矩阵
	int numVextexes, numEdges;  //图中当前顶点数和边数
}MGraph;


bool visited[MAXVEX];  //访问记录
//DFS递归算法
void DFS(MGraph G, int i) {
	int j;
	visited[i] = true;  //首先标记为已访问
	//接题意要求的操作
	cout << G.vexs[i];
	for (j = 0; j < G.numVextexes; ++j) {
		//如果还有邻接点未被访问,则继续访问
		if (G.arc[i][j] == 1 && !visited[j])
			DFS(G,j);
	}
}
//DFS操作
void DFSTraverse(MGraph G) {
	int i;
	//初始化访问记录表
	for (i = 0; i < G.numVextexes; ++i) {
		visited[i] = false;
	}
	//遍历每一个顶点
	for (i = 0; i < numVextexes; ++i) {
		if (!visited[i])
			DFS(G, i);
	}
}

邻接表实现

typedef char VertexType;
typedef int EdgeType;
#define MAXVEX 100
typedef struct EdgeNode {
	int adjvex;
	EdgeType weight;
	struct EdgeNode *next;
}EdgeNode;

typedef struct VertexNode {
	VertexType data;
	EdgeNode *firstedge;
}VertexNode, AdjList[MAXVEX];

typedef struct {
	AdjList adjList;
	int numVextexes, numEdges;
}GraphAdjList;


bool visited[MAXVEX];  //访问记录
void DFS(GraphAdjList G, int i) {
	EdgeNode *p;
	cout << G.adjList[i].data;  //操作
	p = G.adjList[i].firstedge;  
	//如果这条路还没走完则继续走
	while (p) {
		if (!visited[p->adjvex])
			DFS(G, p->adjvex);
		p = p->next;
	}
}
//DFS操作
void DFSTraverse(GraphAdjList G) {
	int i;
	//初始化访问记录
	for (i = 0; i < numVextexes; ++i) {
		visited[i] = false;
	}
	//遍历每一个顶点
	for (i = 0; i < numVextexes; ++i) {
		if (!visited[i])
			DFS(G, i);
	} 
}

BFS(广度优先遍历)

广度优先遍历( B r e a d t h Breadth Breadth F i r s t First First S e r a c h Serach Serach),又称广度优先搜索,简称 B F S BFS BFS
图论(四) 图的遍历 【DFS、BFS】_第1张图片

邻接矩阵实现

void BFSTraverse(MGraph G) {
	int i,j;
	queue<int> q;
	for (i = 0; i < G.numVertexes; ++i) {
		visited[i] = false;
	}
	for (i = 0; i < G.numVextexes; ++i) {
		if (!visited[i])
			visited[i] = true;
		cout << G.vexs[i];
		q.push(G.vexs[i]);
		while (!q.empty()) {
			VextexType temp = q.pop();
			for (j = 0; j < G.numVextexes; ++j) {
				if (G.arc[i][j] == 1 && !visited[j]) {
					visited[j] = true;
					cout << G.vexs[j];
					q.push(G.vexs[j]);
				}
			}
		}
	}
}

邻接表实现

void BFSTraverse(GraphAdjList G) {
	int i;
	EdgeNode *p;
	queue<int> q;
	//初始化访问记录
	for (i = 0; i < G.numVextexes; ++i) {
		visited[i] = false;
	}
	//遍历每个顶点
	for (i = 0; i < G.numVextexes; ++i) {
		if (!visited[i]) {
			visited[i] = true;
		}
		cout << G.adjList[i].data;
		q.push(i);
		while (!q.empty()) {
			q.pop();
			p = G.adjList[i].firstedge;
			while (p) {
				if (!visited[p->adjvex]) {
					visited[p->adjvex] = true;
					cout << G.adjList[p->adjvex].data;
					q.push(p->adjvex);
					p = p->next;
				}
			}
		}
	}
}

你可能感兴趣的:(【图论】)