图的深度优先遍历和广度优先遍历
算法实现原理见注释
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Created by yangrs on 2020/6/6.
*/
public class GraphTraversal {
public static void main(String[] args) {
double[][] adjacentMatrix = new double[][]{
{0,1,0,0,0,0,0,1,0}
,{1,0,1,0,1,0,0,0,0}
,{0,1,0,1,0,0,0,0,0}
,{0,0,1,0,1,1,0,0,0}
,{0,1,0,1,0,0,0,0,0}
,{0,0,0,1,0,0,1,1,0}
,{0,0,0,0,0,1,0,0,0}
,{1,0,0,0,0,1,0,0,1}
,{0,0,0,0,0,0,0,1,0}
};
Graph graph = new Graph(adjacentMatrix);
System.out.println("DFS");
graph.nodeReset();
graph.dfs(graph.getNodes()[0]);
System.out.println("BFS");
graph.nodeReset();
graph.bfs(graph.getNodes()[0]);
}
}
class Graph {
private double[][] adjacentMatrix;
private int size;
private Node[] nodes;
public Graph(double[][] adjacentMatrix, int size) {
this.adjacentMatrix = adjacentMatrix;
this.size = size;
this.nodes = new Node[this.size];
for (int id = 0; id < this.size; id++) {
this.nodes[id] = new Node(id,null);
}
for (int i = 0; i < this.adjacentMatrix.length; i++) {
for (int j = 0; j < this.size; j++) {
if (0 == this.adjacentMatrix[i][j]) continue;
if (null == this.nodes[i].getChilds()) {
this.nodes[i].setChilds(new ArrayList<>());
}
this.nodes[i].getChilds().add(nodes[j]);
}
}
}
public Graph(double[][] adjacentMatrix) {
this.adjacentMatrix = adjacentMatrix;
this.size = adjacentMatrix.length;
this.nodes = new Node[this.size];
for (int id = 0; id < this.size; id++) {
this.nodes[id] = new Node(id,null);
}
for (int i = 0; i < this.adjacentMatrix.length; i++) {
for (int j = 0; j < this.size; j++) {
if (0 == this.adjacentMatrix[i][j]) continue;
if (null == this.nodes[i].getChilds()) {
this.nodes[i].setChilds(new ArrayList<>());
}
this.nodes[i].getChilds().add(nodes[j]);
}
}
}
public Graph() {
}
public void nodeReset() {
for (Node node : this.nodes) {
node.setVisited(false);
}
}
/**
* 深度优先搜索,每次访问一个节点,将节点入栈并标记为已访问,再依次访问节点的子节点。如果当前节点没有子节点或子节点均已被访问则出栈。
* @param node
*/
public void dfs(Node node) {
node.setVisited(true);
if (null != node.getChilds() && !node.getChilds().isEmpty()) {
List<Node> children = node.getChilds();
for (Node child : children) {
if (!child.isVisited()) {
dfs(child);
}
}
}
System.out.println(node.getValue());
}
/**
* 广度优先搜索,借助队列实现,先将根节点入队。然后做循环操作,每次循环弹出队头节点并将队头节点的子节点全部入队。循环操作直到对列为空
* @param node
*/
public void bfs(Node node) {
Queue<Node> candidateQueue = new LinkedBlockingQueue<>();
candidateQueue.add(node);
node.setVisited(true);
while(!candidateQueue.isEmpty()) {
Node outNode = candidateQueue.poll();
System.out.println(outNode.getValue());
if (null != outNode.getChilds() && !outNode.getChilds().isEmpty()) {
List<Node> children = outNode.getChilds();
for (Node child : children) {
if (!child.isVisited()) {
child.setVisited(true);
candidateQueue.add(child);
}
}
}
}
}
public double[][] getAdjacentMatrix() {
return adjacentMatrix;
}
public void setAdjacentMatrix(double[][] adjacentMatrix) {
this.adjacentMatrix = adjacentMatrix;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public Node[] getNodes() {
return nodes;
}
public void setNodes(Node[] nodes) {
this.nodes = nodes;
}
}
class Node {
private int value;
private boolean visited = false;
private List<Node> childs = new ArrayList<>();
public Node(int value, List<Node> childs) {
this.value = value;
this.childs = childs;
}
public Node() {
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public boolean isVisited() {
return visited;
}
public void setVisited(boolean visited) {
this.visited = visited;
}
public List<Node> getChilds() {
return childs;
}
public void setChilds(List<Node> childs) {
this.childs = childs;
}
}