import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
/**
* @author Drug
* @create 2020-05-11 12:16
*/
public class Graph {
//顶点集合
private ArrayList<String> vertexList;
//邻接矩阵
private int[][] edges;
//边数目
private int numOfEdges;
//访问标记
private boolean[] isVisited;
//test
public static void main(String[] args) {
int n = 8;
// String Vertexs[] = {"A", "B", "C", "D", "E"};
String Vertexs[] = {"1", "2", "3", "4", "5", "6", "7", "8"};
//创建图对象
Graph graph = new Graph(n);
//循环的添加顶点
for (String vertex : Vertexs) {
graph.insertVertex(vertex);
}
// 添加边
// 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.insertEdge(0, 1, 1);
graph.insertEdge(0, 2, 1);
graph.insertEdge(1, 3, 1);
graph.insertEdge(1, 4, 1);
graph.insertEdge(3, 7, 1);
graph.insertEdge(4, 7, 1);
graph.insertEdge(2, 5, 1);
graph.insertEdge(2, 6, 1);
graph.insertEdge(5, 6, 1);
graph.showGraph();
System.out.println("深度优先遍历");
graph.dfs();
System.out.println();
System.out.println("广度优先遍历");
graph.bfs();
}
//构造器
public Graph(int n) {
vertexList = new ArrayList<>(n);
edges = new int[n][n];
numOfEdges = 0;
}
/**
* 给v1,v2边添加权值
*
* @param v1
* @param v2
* @param wight
*/
public void insertEdge(int v1, int v2, int wight) {
edges[v1][v2] = wight;
edges[v2][v1] = wight;
numOfEdges++;
}
/**
* 遍历图
*/
public void showGraph() {
for (int[] edge : edges) {
System.out.println(Arrays.toString(edge));
}
}
/**
* 返回顶点数目
*
* @return
*/
public int getNumOfVertex() {
return vertexList.size();
}
/**
* 得到边的数目
*/
public int getNumOfEdges() {
return numOfEdges;
}
/**
* 返回结点i(下标)对应的数据 0->"A" 1->"B" 2->"C"
*
* @param i
* @return
*/
public String getValueByIndex(int i) {
return vertexList.get(i);
}
/**
* 返回v1和v2的权值
*
* @param v1
* @param v2
* @return
*/
public int getWeight(int v1, int v2) {
return edges[v1][v2];
}
/**
* 插入结点
*
* @param vertex
*/
public void insertVertex(String vertex) {
vertexList.add(vertex);
}
/**
* 获得i的第一个临界顶点
*
* @param index
* @return
*/
public int getFirstNeighbour(int index) {
for (int i = 0; i < vertexList.size(); i++) {
if (edges[index][i] == 1) {
return i;
}
}
return -1;
}
/**
* 获得n的下一个临界顶点
*
* @param n
* @param index
* @return
*/
public int getNextNeighbour(int n, int index) {
for (int i = index + 1; i < vertexList.size(); i++) {
if (edges[n][i] == 1) {
return i;
}
}
return -1;
}
/**
* 从n开始深度优先遍历
*
* @param n
*/
private void dfs(boolean[] isVisited, int n) {
//输出该点
System.out.print(" ->" + getValueByIndex(n));
//将该点置为访问过
isVisited[n] = true;
int w = getFirstNeighbour(n);
while (w != -1) {
//如果第一个点没被访问过
if (!isVisited[w]) {
//递归
dfs(isVisited, w);
}
//如果被访问过了
w = getNextNeighbour(n, w);
}
}
/**
* 深度优先遍历
*/
public void dfs() {
isVisited = new boolean[getNumOfVertex()];
for(int i=0;i<vertexList.size();i++){
if(!isVisited[i]){
dfs(isVisited,i);
}
}
}
/**
* 广度优先遍历
* @param isVisited
* @param i
*/
private void bfs(boolean[] isVisited, int i){
//用于存放遍历顺序
LinkedList<Integer> queue = new LinkedList<Integer>();
//输出当前节点
System.out.print(" =>"+getValueByIndex(i));
//设置访问过
isVisited[i] = true;
//队列添加节点
queue.addLast(i);
//当队列非空时一直执行
while(!queue.isEmpty()){
Integer u = queue.removeFirst();
//获得第一个临界顶点
int w = getFirstNeighbour(u);
//当存在临界顶点时,持续访问
while( w != -1){
//还没有访问过
if(!isVisited[w]){
//输出当前节点
System.out.print(" =>"+getValueByIndex(w));
//设置访问过
isVisited[w] = true;
//队列添加节点
queue.addLast(w);
}
//获得下一个临界顶点
w = getNextNeighbour(u,w);
}
}
}
/**
* 广度优先遍历
*/
public void bfs(){
isVisited = new boolean[getNumOfVertex()];
for(int i=0; i<getNumOfVertex();i++){
//没有访问过
if(!isVisited[i]){
bfs(isVisited,i);
}
}
}
}
java图的深度优先遍历(dfs)和广度优先遍历(bfs)代码实现
最新推荐文章于 2023-10-23 22:12:03 发布