广度优先( Breadth-First-Search, BFS)
这是一种图形搜索算法,彻底地搜索整张图,直到找到结果为止。
一般的实现里,其邻居节点尚未被检验过的节点会被放置在一个称为open 容器里面,而未检验过的节点则 会被放置在称为closed的容器中,形成张open-closed表。
算法描述如下: 1. 将顶点入队列 2.当队列为非空时,继续执行,否则算法结束
a. 出队列取得队列头顶点V;访问并标记为已访问
b.查找顶点V的第一个邻接顶点W
c.若V的邻接顶点W未被访问过的,则W入队列
d.继续查找顶点V的另一个新的邻接顶点W,转到步骤2。
设置两个链表 closedList 存放已经访问过的节点 openList 存放即将访问的节点
广度优先算法可以总结为,按层次来遍历的,先是根节点,然后是第二层子节点,依次是第三层子节点,将节点分别放入队列中,每次从队列中探出首元素,遍历后的点放入closed表中,还未遍历的店放入open表中,当open表为空时,则整个数遍历完全。
实现的代码如下:
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class breadthFirstSearch {
public static class Node{
List neighbors;
Node pathParent;
String name;
public Node(String name){
this.name = name;
neighbors = new LinkedList();
}
public String toString(){
return name;
}
}
public static void main(String[] args){
Node nodeA = new Node("A");
Node nodeB = new Node("B");
Node nodeC = new Node("C");
Node nodeD = new Node("D");
Node nodeE = new Node("E");
Node nodeF = new Node("F");
Node nodeG = new Node("G");
Node nodeH = new Node("H");
/*
* Construct Trees
*/
nodeA.neighbors.add(nodeC);
nodeA.neighbors.add(nodeD);
nodeA.neighbors.add(nodeE);
nodeB.neighbors.add(nodeE);
nodeC.neighbors.add(nodeA);
nodeC.neighbors.add(nodeD);
nodeC.neighbors.add(nodeF);
nodeD.neighbors.add(nodeA);
nodeD.neighbors.add(nodeC);
nodeE.neighbors.add(nodeA);
nodeE.neighbors.add(nodeB);
nodeE.neighbors.add(nodeG);
nodeF.neighbors.add(nodeC);
nodeF.neighbors.add(nodeH);
nodeG.neighbors.add(nodeE);
nodeH.neighbors.add(nodeC);
nodeH.neighbors.add(nodeF);
breadthFirstSearch bfs = new breadthFirstSearch();
System.out.println("From A to B:" + bfs.search(nodeA,nodeF));
}
public List search(Node startNode,Node goalNode){
LinkedList closedList = new LinkedList();
LinkedList openList = new LinkedList();
openList.add(startNode);
startNode.pathParent = null;
while(!openList.isEmpty()){
Node node = (Node)openList.removeFirst();
if(node == goalNode){
//return constructPath(goalNode);
//路径就是closed表中的顺序
return constructPath(closedList);
}else{
closedList.add(node);
Iterator i = node.neighbors.iterator();
while(i.hasNext()){
Node neighborNode = (Node)i.next();
if(!closedList.contains(neighborNode) &&
!openList.contains(neighborNode)){
neighborNode.pathParent = node;
openList.add(neighborNode);
}
}
}
}
return null;
}
public List constructPath(LinkedList list){
//LinkedList path = new LinkedList();
System.out.println("广度优先路径:" + list.toString());
// while(node.pathParent != null){
// path.addFirst(node);
// node = node.pathParent;
// }
return list;
}
}