广度优先算法的步骤:
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),