廣度優先算法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),

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM