图的邻接矩阵表示法
参考b站视频
用一维数组存储顶点信息,用二维数组存储顶点与顶点之间的边关系
创建接口类
先定义图要实现的方法
package com.testgraph;
public interface Graph<V> {//获取顶点数int getVerticesSize();//获取边数int getEdgesSize();//增加一个顶点void addVertex(V v);//增加一条边void addEdge(V from,V to);//增加一条带权值的边void addEdge(V from, V to,int weight);//删除一个顶点void removeVertex(V v);//删除一条边void removeEdge(V from, V to);//深度遍历void dfs();//广度遍历void bfs();//打印图void displayGraph();
}
实现接口的方法
- 用一维数组存储顶点信息
- 用二维数组存储顶点与顶点之间的边关系
- 顶点数量,用于实际存储的顶点的数量
- size规模,最大可以存储size-1个顶点
package com.testgraph;import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;public class MatrixGraph<V> implements Graph<V> {// 顶点的数量private int verticesNum;// 边的数量private int edgesNum;// 顶点的存储private List<V> verticesList;// 边的存储private int[][] edgesList;// 规模private int size;// 初始化图public MatrixGraph(int size) {// TODO Auto-generated constructor stubthis.verticesList = new ArrayList<>();this.edgesList = new int[size][size];this.size = size;this.verticesNum = 0;this.edgesNum = 0;}@Overridepublic int getVerticesSize() {// TODO Auto-generated method stubreturn this.verticesNum;}@Overridepublic int getEdgesSize() {// TODO Auto-generated method stubreturn this.edgesNum;}@Overridepublic void addVertex(V v) {/**** 判断顶点数组是否存在该顶点 1. 存在则不添加 2. 不存在判断是否已经超上限 1)不超上限则添加到数组中*/int index = this.verticesList.indexOf(v);if (index > -1) {System.out.println(v.toString() + "顶点已经存在!!");} else {this.verticesNum++;if (this.verticesNum + 1 > this.size) {System.out.println("顶点数超上限");this.verticesNum--;} else {this.verticesList.add(v);}}}@Overridepublic void addEdge(V from, V to) {/**** 找出顶点在顶点数组中下标 1. 不存在则不添加 2. 存在则 将二维数组中置为1*/this.addEdge(from, to, 1);}@Overridepublic void addEdge(V from, V to, int weight) {/**** 找出顶点在顶点数组中下标 1. 不存在则不添加 2. 存在则 将二维数组中置为weight*/int fromIndex = this.verticesList.indexOf(from);int toIndex = this.verticesList.indexOf(to);if (fromIndex < 0) {System.out.println("不存在" + from.toString() + "该顶点");} else if (toIndex < 0) {System.out.println("不存在" + to.toString() + "该顶点");} else {this.edgesList[fromIndex][toIndex] = weight;this.edgesNum++;System.out.println(from.toString() + "===>" + to.toString() + "添加边成功!!!");}}@Overridepublic void removeVertex(V v) {/**** 找出顶点在顶点数组中下标 1. 不存在则退出 2. 存在则 将二维数组左上移(谁等于index,则谁向前移动)*/int index = this.verticesList.indexOf(v);boolean flag = this.verticesList.remove(v);if (flag) {// 删除边数---startfor (int i = 0; i < this.verticesNum; i++) {if (this.edgesList[i][index] > 0) {this.edgesNum--;this.edgesList[i][index] = 0;}}for (int j = 0; j < this.verticesNum; j++) {if (this.edgesList[index][j] > 0) {this.edgesNum--;this.edgesList[index][j] = 0;}}// 删除边数---endfor (int i = index; i < this.verticesNum; i++) {for (int j = 0; j < this.verticesNum; j++) {this.edgesList[i][j] = this.edgesList[i + 1][j];}}for (int i = 0; i < this.verticesNum; i++) {for (int j = index; j < this.verticesNum; j++) {this.edgesList[i][j] = this.edgesList[i][j + 1];}}this.verticesNum--;System.out.println(v.toString() + "删除成功!!");} else {System.out.println(v.toString() + "元素不存在!");}}@Overridepublic void removeEdge(V from, V to) {/**** 找出顶点在顶点数组中下标 1. 不存在则退出 2. 存在则 将二维数组中对应边的关系置为0*/int fromIndex = this.verticesList.indexOf(from);int toIndex = this.verticesList.indexOf(to);if (fromIndex < 0) {System.out.println("不存在" + from.toString() + "该顶点");} else if (toIndex < 0) {System.out.println("不存在" + to.toString() + "该顶点");} else {this.edgesList[fromIndex][toIndex] = 0;this.edgesNum--;System.out.println("删除边成功:" + from.toString() + "=XX=>" + to.toString());}}@Overridepublic void dfs() {// 1.建立一个访问数组boolean[] beVisited = new boolean[this.verticesNum];// 2.访问初始节点System.out.print("深度度优先访问:");System.out.print(this.verticesList.get(0));// 3.将初始节点在访问数组置为truebeVisited[0] = true;this.dfs(0, 1, beVisited);System.out.println();}/*** verticesIndex顶点下标 matrixVerticesIndex顶点的邻接表下标*/public void dfs(int verticesIndex, int matrixVerticesIndex, boolean[] beVisited) {// 遍历该顶点的所有邻接节点for (int y = matrixVerticesIndex; y < this.verticesNum; y++) {// 存在路,未访问if (this.edgesList[verticesIndex][y] != 0 && !beVisited[y]) {beVisited[y] = true;// 访问System.out.print("==>" + this.verticesList.get(y));// 深度继续访问该邻接节点的邻接节表this.dfs(y, 0, beVisited);}}}@Overridepublic void bfs() {// 1.建立一个访问数组、一个队列boolean[] beVisited = new boolean[this.verticesNum];Queue<Integer> queue = new LinkedList<>();// 2.访问初始节点System.out.print("广度优先访问:");System.out.print(this.verticesList.get(0));// 3.将初始节点在访问数组置为true,将节点纳入队列中beVisited[0] = true;queue.offer(0);while (!queue.isEmpty()) {// 提取节点int vertexIndex = queue.poll();for (int y = 0; y < this.verticesNum; y++) {// 存在边,未访问if (this.edgesList[vertexIndex][y] != 0 && !beVisited[y]) {// 入列queue.offer(y);// 访问System.out.print("==>" + this.verticesList.get(y));beVisited[y] = true;}}}System.out.println();}@Overridepublic void displayGraph() {// 打印System.out.println("图的顶点" + this.verticesList);System.out.println("图的顶点数:" + getVerticesSize());System.out.println("图的边数为: " + getEdgesSize());System.out.println("图的临接矩阵: ");System.out.print(" ");for (int i = 0; i < this.verticesNum; i++) {System.out.print(this.verticesList.get(i) + " ");}System.out.println();for (int i = 0; i < this.verticesNum; i++) {System.out.print(this.verticesList.get(i) + ": [ ");for (int j = 0; j < this.verticesNum; j++) {System.out.print(" " + this.edgesList[i][j] + " ");}System.out.println("]");}}}
测试类
package com.testgraph;public class GraphTest {public static void main(String []args) {//MatrixGraph graph = new MatrixGraph(10);LinkGraph graph = new LinkGraph(15);graph.addVertex("北京");graph.addVertex("上海");graph.addVertex("广东");graph.addVertex("四川");graph.addVertex("湖南");graph.addVertex("吉林");graph.addVertex("海南");graph.addVertex("重庆");graph.addVertex("台湾");graph.addVertex("香港");graph.addVertex("陕西");graph.addVertex("贵州");graph.addVertex("河北");graph.addVertex("河南");graph.addEdge("北京","上海");graph.addEdge("北京","广东");graph.addEdge("四川","广东");graph.addEdge("湖南","广东");graph.addEdge("广东","上海");graph.addEdge("上海","四川");graph.addEdge("台湾","上海");graph.addEdge("重庆","广东");graph.addEdge("香港","北京");graph.addEdge("贵州","上海");graph.addEdge("吉林","海南");graph.addEdge("四川","海南");graph.addEdge("广东","吉林");graph.displayGraph();//graph.removeEdge("湖南","广东");//graph.displayGraph();//graph.removeVertex("广东");//graph.displayGraph();graph.dfs();graph.bfs();}
}