BFS模板

搜索只是用来遍历连通图的,或许只是解决问题的一部分,还是要具体问题具体分析。
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';
                }
            }
        }
    }

你可能感兴趣的:(数据结构,BFS,搜索,Java,LeetCode)