基本代码:
void BFS(int** graph, int size, int start, bool* visited) {
Queue q = createQueue(size);
enqueue(&q, start);
visited[start] = true;
while (!isEmpty(&q)) {
int cur = dequeue(&q);
printf("%d ", cur);
for (int i = 0; i < size; i++) {
if (graph[cur][i] == 1 && !visited[i]) {
enqueue(&q, i);
visited[i] = true;
}
}
}
}
// 示例调用
bool visited[size];
memset(visited, false, size * sizeof(bool));
BFS(graph, size, start, visited);
基本运行原理:
-
首先将起始节点放入队列中。
-
从队列中取出下一个节点,并遍历该节点的相邻节点。
-
对于每个相邻节点,如果该相邻节点没有被访问过,则将其标记为已访问并放入队列中等待后续访问。
-
重复步骤 2 和步骤 3,直到整张图都被访问过或者找到目标节点。
在进行 BFS 时,从起始节点开始,逐层扩展。通过队列作为辅助数据结构,保证了每层中的节点按照从左到右的顺序依次加入队列,并先访问离起始节点近的节点,从而实现了广度优先搜索。BFS 通常用于求解最短路径或者能够通过少量步数到达的问题。
-
需要使用队列来存储每次扩展的节点,以保证扩展的节点顺序是按照层级逐个访问的。
-
需要对已经访问过的节点做标记,防止重复访问。在访问到新节点时,判断该节点是否已经被访问过。
-
在某些情况下,如果图中存在环,可能导致广度优先搜索进入死循环,因此需要设置最大访问次数或者最大访问深度,避免陷入死循环。
-
广度优先搜索适用于求解最短路径问题,即在无权图或者权值非负的有权图中寻找从起点到终点的最短路径。
-
广度优先搜索的时间复杂度为 O(V+E),其中 V 表示图中的节点数,E表示图中的边数。
广度优先搜索有以下两个常见的扩展:
-
双向广度优先搜索(Bidirectional BFS):在从初始节点开始的广度优先搜索过程中,同样从目标节点开始进行广度优先搜索。当两个搜索的队列相遇时,即找到了从初始节点到目标节点的最短路径。双向广度优先搜索可以显著减少搜索的时间和空间复杂度。
-
带优先级的广度优先搜索(A*算法):在广度优先搜索的基础上,引入启发函数(Heuristic Function),在扩展节点的时候优先选取启发式函数值更小的节点进行拓展,以此来减少搜索的时间和空间复杂度。该算法广泛应用于图搜索、路径规划及人工智能等领域。