搜索只是用来遍历连通图的,或许只是解决问题的一部分,还是要具体问题具体分析。
BFS可用来查找最短路径、前提是路径代价一样
模板一
/**
* Return the length of the shortest path between root and target node.
*/
int BFS(Node root, Node target)
{
Queue<Node> queue; // store all nodes which are waiting to be processed
int step = 0; // number of steps neeeded from root to current node
// initialize
add root to queue;
// BFS
while (queue is not empty)
{
step = step + 1;
// iterate the nodes which are already in the queue
int size = queue.size();
for (int i = 0; i < size; ++i)
{
Node cur = the first node in queue;
if cur is target
return step - 1;
for (Node next : the neighbors of cur)
{//这里常用一个二维方向数组实现
add next to queue;
}
remove the first node from queue;
}
}
return -1; // there is no path from root to target
}
/*如代码所示,在每一轮中,队列中的结点是等待处理的结点。
在每个更外一层的 while 循环之后,我们距离根结点更远一步。变量 step 指示从根结点到我们正在访问的当前结点的距离。*/
模板二
有时,确保我们永远不会访问一个结点两次很重要。否则,我们可能陷入无限循环。如果是这样,我们可以在上面的代码中添加一个访问数组、或是修改搜索的参数的值来避免重复搜索。这是修改后的伪代码:
/**
* Return the length of the shortest path between root and target node.
*/
int BFS(Node root, Node target) {
Queue<Node> queue; // store all nodes which are waiting to be processed
Set<Node> used; // store all the used nodes
int step = 0; // number of steps neeeded from root to current node
// initialize
add root to queue;
add root to used;
// BFS
while (queue is not empty) {
step = step + 1;
// iterate the nodes which are already in the queue
int size = queue.size();
for (int i = 0; i < size; ++i) {
Node cur = the first node in queue;
if cur is target
return step - 1;
for (Node next : the neighbors of cur) {
if (next is not in used) {
add next to queue;
add next to used;
}
}
remove the first node from queue;
}
}
return -1; // there is no path from root to target
}
例子:岛屿的个数
链接:岛屿的个数
//BFS,使用队列的非递归广度优先搜索
private int m, n;
private int stepArr[][] = {{0,1},{1,0},{0,-1},{-1,0}};//方向数组
public int numIslands(char[][] grid)
{
if(null == grid || grid.length == 0 || grid[0].length == 0)
return 0;
m = grid.length;//行
n = grid[0].length;//列
int count = 0;
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
if(grid[i][j] == '1') //遍历、后BFS,BFS一次计数+1
{
bfs(grid, i, j);
System.out.println();
count++;
}
}
}
return count;
}
public void bfs(char[][] grid, int i, int j)
{
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(i * n + j);
System.out.println("x"+i+" y"+j);
grid[i][j] = '0';
while(null != queue.peek())
{
int num = queue.poll();
i = num / n;
j = num % n;
for(int k = 0; k < 4; k++)
{//四个方向!伪代码中的 for (Node next : the neighbors of cur)
int x =i + stepArr[k][0];
int y =j + stepArr[k][1];
if(x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1')
{
queue.add(x * n + y);
System.out.println("x"+x+" y"+y);
grid[x][y] = '0';
}
}
}
}