水一篇,注释挺详细
package zzh0420;
import java.util.*;
public class GraphTest {
public static void main(String[] args) {
//测试一把bfs
int n = 5;
Graph graph = new Graph(n);
String vertex[] = {"A","B","C","D","E"};
//将顶点插入到图中
for(int i = 0;i < n;i++){
graph.vertexList.add(i,vertex[i]);
}
//将边插入到图中
graph.insertEdges(0,1,1);
graph.insertEdges(0,2,1);
graph.insertEdges(1,2,1);
graph.insertEdges(1,3,1);
graph.insertEdges(1,4,1);
//展示一下邻接矩阵标识出来的图
graph.show();
//测试dfs
// System.out.println("深度优先搜索");
// graph.dfs();
//测试bfs
System.out.println("广度优先搜索");
graph.bfs();
}
}
class Graph{
public ArrayList<String> vertexList; //存储顶点集合
private int[][] edges; //存储邻接矩阵
private int numOfEdges; //表示边的个数
private boolean isVisited[];//记录某个节点是否被访问
public Graph(int n){
isVisited = new boolean[n];
vertexList = new ArrayList<>(n);
edges = new int[n][n];
}
//插入顶点
public void insertVertex(String vertex){
vertexList.add(vertex);
}
//插入边
public void insertEdges(int v1,int v2,int weight){
edges[v1][v2] = weight;
edges[v2][v1] = weight;
numOfEdges++;
}
//显示对应的矩阵
public void show(){
for(int[] link : edges){
System.out.println(Arrays.toString(link));
}
}
//返回v1 v2对应的值
public int getWeight(int v1,int v2){
return edges[v1][v2];
}
//返回节点i对应下标的数据
public String getIndex(int i){
return vertexList.get(i);
}
//得到边的数目
public int getNumOfEdges(){
return numOfEdges;
}
//得到顶点的数目
public int getNumOfVertex(){
return vertexList.size();
}
//得到当前顶点的邻接顶点
public int getNeighbour(int i){
for(int j = 0;j < vertexList.size();j++){
if(edges[i][j] > 0){
return j;
}
}
return -1;
}
//得到下一个顶点的邻接顶点
/**
*
* @param i 表示当前顶点
* @param j 表示当前顶点的邻接顶点
* @return 返回当前顶点临界顶点的临界顶点
*/
public int getNextNeighbour(int i,int j){
for(int a = j + 1;a < vertexList.size();a++){
if(edges[i][a] > 0){
return a;
}
}
return -1;
}
//深度优先搜索算法
private void dfs(boolean[] isVisited,int index){
System.out.print(getIndex(index) + "->");//先输出当前顶点信息
isVisited[index] = true;//标记当前顶点为已访问
int w = getNeighbour(index);//获取它的邻接顶点
while(w != -1){//说明有邻接顶点
if(!isVisited[w]){//如果该顶点没有被访问过
dfs(isVisited,w);
}else{//该顶点被访问过
w = getNextNeighbour(index,w);
}
}
}
//重载bfs
public void dfs(){
for(int i = 0;i < getNumOfVertex();i++){
if(!isVisited[i]){
dfs(isVisited,i);
}
}
}
//广度优先搜索算法
private void bfs(boolean[] isVisited,int index){
System.out.print(getIndex(index) + "->");
isVisited[index] = true;
int u;//表示队列头节点对应的下标
int w;//表示邻接节点
LinkedList queue = new LinkedList();
queue.addLast(index);
while(!queue.isEmpty()) {
//取出队列的头节点
u = (Integer) queue.removeFirst();//自动拆箱功能
//得到第一个邻接点的下标
w = getNeighbour(u);
while (w != -1) {
//是否访问过
if (!isVisited[w]) {
System.out.println(getIndex(w) + "->");
//标记为已经访问
isVisited[w] = true;
//入队列
queue.addLast(w);
}
//以u为前驱节点,找w后面的下一个邻接节点
w = getNextNeighbour(u, w);//体现出广度优先
}
}
}
//重载bfs
public void bfs(){
for(int i = 0;i < vertexList.size();i++){
if(!isVisited[i]){
bfs(isVisited,i);
}
}
}
}