zoukankan      html  css  js  c++  java
  • 广度优先算法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),
  • 相关阅读:
    SQL-修改表名,列名
    MySQL必知必会-7、数据过滤
    排序
    Leetcode题解-双指针
    MySQL必知必会-6、过滤数据
    MySQL必知必会-5、排序检索数据
    MySQL必知必会-4、检索数据
    Java容器源码分析-LinkedList
    Java容器源码分析-CopyOnWriteArrayList
    Java容器源码分析-Vector
  • 原文地址:https://www.cnblogs.com/jkavor/p/7404616.html
Copyright © 2011-2022 走看看