广度优先算法Java实现以及最短路径搜索

广度优先算法的步骤:

1.选定一个起始节点;

2.以选定节点为中心,所有与该节点相邻节点为备选节点(其中,在之前已经访问过的节点不得再纳入相邻节点),并将这些备选节点放入一个先进先出队列中,;

3.依次取出先进先出队列中的节点,并求得该节点的相邻节点放入先进先出队列中;

4.循环进行2、3步骤;知道先进先出队列为空(搜索结束的标志);

接下来直接上java代码咯:

package Graph;
import java.util.LinkedList;

/*****
 * 
 * 从左上角到右下角,最短路径;
 * 广度搜索法;
 * 
 * *********/
public class BFS {
    /*****重要组成-方向******/
    int[][] direct={{0,1},{0,-1},{-1,0},{1,0}};//四个方向,上下左右
    /*****重要组成-标记******/
    int[][] arc=new int[4][4];//辅助标记数组
    /******输入数组*****/
    int[][] array={
            {1,2,3,4},
            {5,6,7,8},
            {9,10,11,12},
            {13,14,15,16}
           };
    public static void main(String[] args) throws InterruptedException {
        new BFS().BFS();
    }
    /*****重要组成-封装数组点,用坐标表示位置******/
     class Node{
         int row;
         int column;
         int round;
         Node(int row,int column,int round) {
            this.row=row;
            this.column=column;
            this.round=round;
        }
    }
    public void BFS(){//广度搜索算法
        Node start=new Node(0,0,0);
        /*****重要组成-待搜索队列的每个对象都是接下来要所搜的值******/
        LinkedList<Node> queue=new LinkedList<>();//待搜索队列
        queue.offer(start);
        arc[0][0]=1;
        /*****重要组成-持续搜索的标志。待搜索队列里有东西******/
        while(!queue.isEmpty()){
            Node temp=queue.poll();
            for(int i=0;i<4;i++){//尝试搜索四个方向的点,如果满足就加入待搜索队列中
                int new_row=temp.row+direct[i][0];
                int new_column=temp.column+direct[i][1];
                if(new_row<0||new_column<0||new_row>=4||new_column>=4)
                    continue;//该方向上出界,考虑下一方向
                if(arc[new_row][new_column]==1)continue;
                arc[new_row][new_column]=1;
                Node next=new Node(new_row, new_column,temp.round+1);
                queue.offer(next);
                System.out.println("数值:"+array[new_row][new_column]+",轮次:"+(temp.round+1));
            }
        }
    }
}

运行结果:

数值:2,轮次:1
数值:5,轮次:1
数值:3,轮次:2
数值:6,轮次:2
数值:9,轮次:2
数值:4,轮次:3
数值:7,轮次:3
数值:10,轮次:3
数值:13,轮次:3
数值:8,轮次:4
数值:11,轮次:4
数值:14,轮次:4
数值:12,轮次:5
数值:15,轮次:5
数值:16,轮次:6

 

以上代码参考了下列博客:http://www.imooc.com/article/17187

面试题中经常会遇到,给定一个0,1矩阵,0表示可走,1表示不可走。求出从左上角到右下角的最短路径?

这里我们就可以用广度优先算法来实现(例子中给定的4*4数组):

import java.util.LinkedList;

public class Main {
    /*****重要组成-方向******/
    int[][] direct={{0,1},{0,-1},{-1,0},{1,0}};//四个方向,上下左右
    /******输入数组*****/
    int[][] array={
            {0,0,0,0},
            {0,0,1,0},
            {0,0,1,0},
            {0,0,1,0}
           };
    public static void main(String[] args) throws InterruptedException {
        new Main().BFS();
    }
    /*****重要组成-封装数组点,用坐标表示位置******/
     class Node{
         int row;
         int column;
         int round;
         Node pre;
         Node(int row,int column,int round,Node pre) {
            this.row=row;
            this.column=column;
            this.round=round;
            this.pre=pre;
        }
    }
    public void BFS(){//广度搜索算法
        Node start=new Node(0,0,0,null);
        /*****重要组成-待搜索队列的每个对象都是接下来要所搜的值******/
        LinkedList<Node> queue=new LinkedList<>();//待搜索队列
        queue.offer(start);
        /*****重要组成-持续搜索的标志。待搜索队列里有东西******/
        while(!queue.isEmpty()){
            Node temp=queue.poll();
            for(int i=0;i<4;i++){//尝试搜索四个方向的点,如果满足就加入待搜索队列中
                int new_row=temp.row+direct[i][0];
                int new_column=temp.column+direct[i][1];
                if(new_row<0||new_column<0||new_row>=4||new_column>=4)
                    continue;//该方向上出界,考虑下一方向
                if(array[new_row][new_column]==1)continue;
                Node next=new Node(new_row, new_column,temp.round+1,temp);
                if(new_row==3&&new_column==3)//找到了出口
                {
                    queue.clear();
                    queue.offerFirst(next);
                    while(next.pre!=null){
                        queue.offerFirst(next.pre);//以前获取父节点
                        next=next.pre;
                    }
                    for(Node node:queue)
                    {
                        System.out.println("("+node.row+","+node.column+"),");
                    }
                }
                array[new_row][new_column]=1;
                queue.offer(next);
            }
        }
    }
}

执行结果:

(0,0),
(0,1),
(0,2),
(0,3),
(1,3),
(2,3),
(3,3),

 

posted @ 2017-08-21 15:20  jkavor  阅读(5582)  评论(0编辑  收藏  举报