广度优先搜索算法常用于通过队列求最短路径,下面只实现了搜索算法
1、算法思想
广度优先搜索算法是通过一层一层的遍历的,遍历思想如下:
1、 选取根节点r
2、 遍历r的子节点,并计算根节点r到子节点的权值,注意的是当前节点的到根节点的权值等于当前节点的父节点到根节点的权值
3、 依次遍历所有节点
4、 所有节点只能遍历一遍,即当一个节点有两个父节点时,只能被一个父节点遍历
例子:先选定1节点,然后会遍历1的子节点2、3,并在遍历的时候计算2、3的权值,2的权值为1,3的权值为5,然后遍历2节点的子节点4、5,计算4、5的节点的权值为,节点4:1+7=8,节点5:1+5=6;之后遍历3节点的子节点,由于5节点已被2节点遍历,那么只遍历6号节点即可,最后其他的节点一次类推,直到遍历所有节点。
2、实现代码
package 搜索.广度优先搜索BFS;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
static int[][] G = { //图
{ 0, 1, 5, -1, -1, -1, -1, -1, -1 },
{ 1, 0, 3, 7, 5, -1, -1, -1, -1 },
{ 5, 3, 0, -1, 1, 7, -1, -1, -1 },
{ -1, 7, -1, 0, 2, -1, 3, -1, -1 },
{ -1, 5, 1, 2, 0, 3, 6, 9, -1 },
{ -1, -1, 7, -1, 3, 0, -1, 5, -1 },
{ -1, -1, -1, 3, 6, -1, 0, 2, 7 },
{ -1, -1, -1, -1, 9, 5, 2, 0, 4 },
{ -1, -1, -1, -1, -1, -1, 7, 4, 0 },
};
static boolean[] status = new boolean[9]; //是否被选中
private static BlockingQueue<Node> blockingQueue = new LinkedBlockingQueue<>(); //遍历队列
private static List<Node> list = new ArrayList<>(); //保存节点的信息
public static void main(String[] ages){
Node node = new Node(1,0,0);
blockingQueue.add(node);
list.add(node);
status[0] = true;
while (!blockingQueue.isEmpty()){
Node node1 = blockingQueue.poll(); // 获取队列首元素
for (int i = 0; i < G[node1.n-1].length; i++){ //循环当前节点的子节点,并排除遍历过的
if (G[node1.n-1][i] != 0 && G[node1.n-1][i] != -1 && !status[i]){
Node node2 = new Node(i+1, node1.n, node1.s+G[node1.n-1][i]);
blockingQueue.add(node2);
list.add(node2);
status[i] = true;
}
}
}
for (Node node1: list){
System.out.println(node1.n+"->"+node1.f+"->"+node1.s);
}
}
}
class Node{
int n; //节点编号
int f; //父节点的编号
int s; //总权值
Node(int n, int f, int s){
this.f =f;
this.n = n;
this.s = s;
}
}
/*
结果
1->0->0
2->1->1
3->1->5
4->2->8
5->2->6
6->3->12
7->4->11
8->5->15
9->7->18
*/