广度优先遍历
广度优先遍历是连通图的一种遍历策略。因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,故得名。
基本思想
- 1、从图中某个顶点V0出发,并访问此顶点;
- 2、从V0出发,访问V0的各个未曾访问的邻接点W1,W2,…,Wk;然后,依次从W1,W2,…,Wk出发访问各自未被访问的邻接点;
- 3、重复步骤2,直到全部顶点都被访问为止。
性质
与深度优先遍历类似,广度优先遍历也有许多有用的特性:
- 1、广度优先生成树
在广度优先遍历中,如果将每次“前进”(纵深)路过的(将被访问的)结点和边都记录下来,就得到一个子图,该子图为以出发点为根的树,称为广度优先生成树。这种情况与深度优先遍历类似。
- 2、最短路径
显然,从v0出发广度优先遍历图,将得到v0到它的各个可达到的路径。我们这里定义路径上的边的数目为路径长度。与深度优先遍历不同,广度优先遍历得到的v0到各点的路径是最短路径(未考虑边权)。
算法:(邻接矩阵实现)
#include <stdio.h>
#include <queue>
using namespace std;
#define N 10
bool visit[N];
// 无向图
//
// 0-----4-----------8
// | | |
// | | |
// 1-----3-----5-----7
// | | |
// | | |
// 2-----------6-----9
//
int matrix[N][N] =
{
0, 1, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
0, 1, 0, 0, 1, 1, 0, 0, 0, 0,
1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 1, 1, 0, 0,
0, 0, 1, 0, 0, 1, 0, 0, 0, 1,
0, 0, 0, 0, 0, 1, 0, 0, 1, 1,
0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 0, 0
};
void BFS(int x)
{
for (int i = 0; i < N; i++) visit[i] = false; // 初始各点均未访问
std::queue<int> q; // BFS类似于二叉树的层次遍历,因此也要用到队列
q.push(x);
visit[x] = 1;
while (!q.empty())
{
int cur = q.front();
printf("%d ", cur);
q.pop();
for (int i = 0; i < N; i++)
{
if (false == visit[i] && 1 == matrix[cur][i])
{
q.push(i);
visit[i] = 1;
}
}
}
}
int main()
{
BFS(0);
getchar();
return 0;
}