目录
1.问题
2.连通的相关概念
3.解决方案
C语言示例实现:
1.问题
无论是图的深度还是广度遍历都是从图的某一条边往下走,那么被孤立的结点怎么被遍历到呢?
2.连通的相关概念
连通:如果从V到W存在一条(无向)路径,则称V和W是连通的
路径:V到W的路径是一系列顶点{ V,V1,V2…,Vn,W }的集合,其中任一对相邻顶点间都有图中的边。路径的长度等于路径中的边数(若带权,则是所有边的权重和)。如果V和W之间的所有顶点都不同,则称为简单路径。
回路:起点等于终点的路径。
连通图:图中任意两顶点均连通。
连通分量:无向图的极大连通子图
□极大顶点数:再加一个顶点就不连通了
□极大边数:包含子图中所有顶点相连的所有边
强连通:有向图中顶点V和W之间存在双向路径,则称V和W是强连通的
强连通图:有向图中任意两点均强连通
强连通分量:有向图的极大强连通子图
3.解决方案
把每一个点都走一遍(BFS,DFS都可),每走一遍就是一个连通分量,把每个连通分量遍历一遍就好!(孤立的点也算一个强连通分量)。
也就是在BFS,DFS外套一个for循环,以图的每一个结点为起始点开始进行遍历,当所有的以不同起始点开始的遍历结束时,所有的连通分量也自然被遍历到了。
伪代码:
void DFS ( Vertex V )
{
visited[ V ] = true;
for ( V 的每个邻接点 W )
if ( !visited[ W ] )
DFS( W );
}
void ListComponents ( Graph G )
{
for ( each V in G )//从新选择起始点来调用遍历方法
if ( !visited[V] ) {
DFS( V ); /*or BFS( V )*/
}
}
C语言示例实现:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_VERTICES 100
typedef struct Graph {
int numVertices;
int adjMatrix[MAX_VERTICES][MAX_VERTICES];
} Graph;
void initializeGraph(Graph *g, int vertices) {
g->numVertices = vertices;
int i;
for (i = 0; i < vertices; i++) {
int j;
for (j = 0; j < vertices; j++) {
g->adjMatrix[i][j] = 0;
}
}
}
void addEdge(Graph *g, int src, int dest) {
g->adjMatrix[src][dest] = 1;
g->adjMatrix[dest][src] = 1; // 如果是无向图
}
// DFS 递归实现
void DFSUtil(Graph *g, int v, bool visited[]) {
visited[v] = true;
printf("%d ", v);
int i;
for (i = 0; i < g->numVertices; i++) {
if (g->adjMatrix[v][i] == 1 && !visited[i]) {
DFSUtil(g, i, visited);
}
}
}
void DFS(Graph *g) {
bool visited[MAX_VERTICES] = {false};
int v;
for (v = 0; v < g->numVertices; v++) {
if (!visited[v]) {
printf("Connected Component: ");
DFSUtil(g, v, visited);
printf("\n");
}
}
}
// BFS 实现
void BFS(Graph *g, int startVertex, bool visited[]) {
int queue[MAX_VERTICES];
int front = 0, rear = 0;
visited[startVertex] = true;
queue[rear++] = startVertex;
while (front != rear) {
int v = queue[front++];
printf("%d ", v);
int i;
for (i = 0; i < g->numVertices; i++) {
if (g->adjMatrix[v][i] == 1 && !visited[i]) {
visited[i] = true;
queue[rear++] = i;
}
}
}
}
void BFSDisconnected(Graph *g) {
bool visited[MAX_VERTICES] = {false};
int v;
for (v = 0; v < g->numVertices; v++) {
if (!visited[v]) {
printf("Connected Component: ");
BFS(g, v, visited);
printf("\n");
}
}
}
int main() {
Graph g;
initializeGraph(&g, 7);
addEdge(&g, 0, 1);
addEdge(&g, 0, 4);
addEdge(&g, 1, 2);
addEdge(&g, 1, 3);
addEdge(&g, 1, 4);
addEdge(&g, 2, 3);
addEdge(&g, 3, 4);
// 添加一些不连通的节点和边
addEdge(&g, 5, 6);
printf("Depth First Search (DFS) Connected Components:\n");
DFS(&g);
printf("Breadth First Search (BFS) Connected Components:\n");
BFSDisconnected(&g);
return 0;
}