今天我们来介绍一下一个简单的图形算法,广度优先搜索(BFS)。这是一种图形搜索算法,从根节点开始,横向的遍历所有节点。

首先我们需要建立一个叫做Vertex 的model(一般常用Node),用作节点。里面包含三个成员变量:数值(int),是否访问过(boolean),和一个子节点的List。 我们先来看代码。

import java.util.ArrayList;
import java.util.List;

public class Vertex {

  // setup private variable for Vertex model
	private int data;
	private boolean visited;
	private List<Vertex> neighbourList;

	public Vertex(int data) {
		this.data = data;
		this.neighbourList = new ArrayList<>();
	}

  // add the son node list for model
	public void addNeighbour(Vertex vertex) {
		this.neighbourList.add(vertex);
	}

	public int getData() {
		return data;
	}

	public void setData(int data) {
		this.data = data;
	}

	public boolean isVisited() {
		return visited;
	}

	public void setVisited(boolean visited) {
		this.visited = visited;
	}

	public List<Vertex> getNeighbourList() {
		return neighbourList;
	}

	public void setNeighbourList(List<Vertex> neighbourList) {
		this.neighbourList = neighbourList;
	}

	// important override toString to print
	@Override
	public String toString() {
		return ""+this.data;
	}
}

接下来我们要写算法部分。我们需要一个过渡容器来存放Vertex。这个过渡容器我用Queue,因为Queue的特点是先进先出。 首先我们将根节点加入Queue,然后读取他的子节点列表,并且将子节点列表中的节点加入Queue。当遍历子节点时候,在读取每个节点的子节点列表加入Queue。这样就实现了横向遍历。如图:

    1
  2   3
456  7 8

Queue: 1 23 456 78

当读取到2 的时候将2 的子节点4,5,6加入Queue,当读取到3的时候将3的子节点7,8加入Queue

代码如下:

import java.util.LinkedList;
import java.util.Queue;

public class BreadthFirstSearch {

	public void bfs(Vertex root) {

		Queue<Vertex> queue = new LinkedList<>();

		root.setVisited(true);
		queue.add(root);

		while( !queue.isEmpty()) {

			// check each node neighbours, print node, add neighbours list at the end of queue

			Vertex actualVertex = queue.remove();
			System.out.print(actualVertex+"-");

			for(Vertex v : actualVertex.getNeighbourList()) {
				if( !v.isVisited()) {
					v.setVisited(true);
					queue.add(v);
				}
			}
		}
	}

}

这样我们就完成了DFS的算法部分,最后只要加入节点执行就可以啦!!

public class Run {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		BreadthFirstSearch bfstest = new BreadthFirstSearch();

		Vertex vertex1 = new Vertex(1);
		Vertex vertex2 = new Vertex(2);
		Vertex vertex3 = new Vertex(3);
		Vertex vertex4 = new Vertex(4);
		Vertex vertex5 = new Vertex(5);
		Vertex vertex6 = new Vertex(6);
		Vertex vertex7 = new Vertex(7);

    /*
           1
        3     5
      4 6    2 7
    */
		vertex1.addNeighbour(vertex3);
		vertex1.addNeighbour(vertex5);
		vertex3.addNeighbour(vertex4);
		vertex3.addNeighbour(vertex6);
		vertex5.addNeighbour(vertex2);
		vertex5.addNeighbour(vertex7);

		bfstest.bfs(vertex1);
	}
}

运行结果:

1-3-5-4-6-2-7-

这样我们就完成了横向的遍历!!