java实现图的DFS和BFS
public class GraphDemo {
/**
* 存储顶点集合
*/
private ArrayList<String> vertexList;
/**
* 存储图对应的领结矩阵
*/
private int[][] edges;
/**
* 表示边的数目
*/
private int numOfEdges;
/**
* 记录是否被访问
*/
private boolean[] isVisited;
public static void main(String[] args) {
// 测试
String[] vertexValues = {"A", "B", "C", "D", "E"};
GraphDemo graph = new GraphDemo(vertexValues.length);
// 循环添加节点
for (String vertexValue : vertexValues) {
// 加节点
graph.insertVertex(vertexValue);
}
// 加边 A-B , A-C , B-C , B-D , B-E
graph.insertEdge(0, 1, 1);
graph.insertEdge(0, 2, 1);
graph.insertEdge(1, 2, 1);
graph.insertEdge(1, 3, 1);
graph.insertEdge(1, 4, 1);
// 深度优先遍历
graph.dfs();
System.out.println();
graph.bfs();
}
public GraphDemo(int n) {
// 初始化矩阵和vertexList
this.edges = new int[n][n];
this.vertexList = new ArrayList<String>();
this.numOfEdges = 0;
this.isVisited = new boolean[n];
}
/**
* 重载
*/
public void bfs() {
isVisited = new boolean[getNumOfVertex()];
for (int i = 0; i < getNumOfVertex(); ++i) {
if (!isVisited[i]) {
bfs(isVisited, i);
}
}
}
/**
* 广度优先遍历
*/
public void bfs(boolean[] isVisited, int i) {
// 队列头节点
int u;
// 邻接节点
int w;
// 队列
LinkedList queue = new LinkedList();
System.out.print(getValueByIndex(i) + " ==> ");
isVisited[i] = true;
queue.add(i);
while (!queue.isEmpty()) {
u = (int) queue.removeFirst();
w = getFirstNeighbor(u);
// w存在
while (w != -1) {
if (!isVisited[w]) {
System.out.print(getValueByIndex(w) + " ==> ");
isVisited[w] = true;
// 入队
queue.addLast(w);
} else {
// 以u找w下一个节点
w = getNextNeighnor(u, w);
}
}
}
}
/**
* 重载
* 考虑到有不与任何节点所连接的点
*/
public void dfs() {
isVisited = new boolean[getNumOfVertex()];
// 遍历所有节点
for (int i = 0; i < getNumOfVertex(); i++) {
if (!isVisited[i]) {
dfs(isVisited, i);
}
}
}
/**
* 深度优先遍历
*/
private void dfs(boolean[] isVisited, int i) {
System.out.print(getValueByIndex(i) + " ==> ");
isVisited[i] = true;
// i的第一个邻接节点
int firstNeighbor = getFirstNeighbor(i);
// 存在
while (firstNeighbor != -1) {
// 没有被访问过
if (!isVisited[firstNeighbor]) {
dfs(isVisited, firstNeighbor);
} else {
// 被访问过
// 以i找firstNeighbor下一个节点
firstNeighbor = getNextNeighnor(i, firstNeighbor);
}
}
}
/**
* @return 第一个相邻节点的下标, 没找到返回-1
*/
public int getFirstNeighbor(int index) {
for (int i = 0; i < vertexList.size(); i++) {
// 如果连通
if (edges[index][i] > 0) {
return i;
}
}
return -1;
}
/**
* 根据前一个邻接节点的下标来获取后一个领接节点下标
*
* @param v1 前一个邻接节点下标
* @param v2 当前节点
* @return 下一个邻接节点的下标
*/
public int getNextNeighnor(int v1, int v2) {
for (int i = v2 + 1; i < vertexList.size(); ++i) {
if (edges[v1][i] > 0) {
return i;
}
}
return -1;
}
/**
* @return 顶点个数
*/
public int getNumOfVertex() {
return vertexList.size();
}
/**
* @return 边的个数
*/
public int getNumOfEdges() {
return numOfEdges;
}
/**
* @param i 节点下标
* @return 下标对应的数据
*/
public String getValueByIndex(int i) {
return vertexList.get(i);
}
/**
* @param v1 v1节点
* @param v2 v2节点
* @return 权值
*/
public int getWeight(int v1, int v2) {
return edges[v1][v2];
}
/**
* 添加节点
*/
public void insertVertex(String vertex) {
vertexList.add(vertex);
}
/**
* 显示矩阵
*/
public void showGraph() {
for (int[] link : edges) {
System.out.println(Arrays.toString(link));
}
}
/**
* 添加边
*
* @param v1 表示点的下标
* @param v2 表示另一个点的下标
* @param weight 权值
*/
public void insertEdge(int v1, int v2, int weight) {
edges[v1][v2] = weight;
edges[v2][v1] = weight;
++numOfEdges;
}
}