使用鄰接矩陣表示圖詳解
說明
-
圖是一種可以實現多對多的數據結構,不像鏈表和樹,他們只能建立一對一的關系,每個節點只有前驅或者后繼節點,不能實現多對多
-
對於圖的描述可以使用鄰接矩陣或者鄰接表
-
使用鄰接矩陣描述圖:
- 創建集合保存圖的頂點
- 創建二維數組即矩陣描述頂點與頂點之間的關系,頂點與頂點之間用權值來描述,若權值為1,表明兩個頂點是相連的,若權值為0,表明兩個頂點不相連
- 考慮如何用二維數組描述???
- 使用有序集合存儲頂點,那么存儲的頂點在集合中是有序的,使用他們在集合中的下標表示它們在數組中的索引
- 二維數組的行和列分別用集合的下標來表示,則能完整的表示各個頂點之間的關系
- 若兩個頂點相連,則他們對應二維數組相應位置的元素為1,否則為0
- 即可實現鄰接矩陣表示圖
-
但是鄰接矩陣有一個問題,就是會浪費大量的空間,比如如果兩個頂點之間沒有連接,也需要用0來表示
-
因此另一種表示圖的方法,可以解決這個問題
-
使用鄰接表描述圖
- 使用鄰接表描述圖,即使用數組+鏈表的方法來表示
- 總共有幾個頂點,則創建幾條鏈表,每條鏈表表示一個頂點和其他頂點的連接關系
- 將每個頂點相關聯的其他頂點使用鏈表連接起來,
- 即可實現鄰接表描述圖
-
本文主要說明使用鄰接矩陣描述圖
-
源碼見下
源碼及分析
package algorithm.datastructor.graph;
import java.util.ArrayList;
import java.util.Arrays;
/**
* @author AIMX_INFO
* @version 1.0
*/
public class Graph {
//使用鄰接矩陣表示圖
//使用集合存儲圖的頂點
private ArrayList<String> vertexList;
//使用二維數組即矩陣描述頂點之間的關系
private int[][] edges;
//邊的個數
private int numOfEdges;
//測試
public static void main(String[] args) {
int n = 5;
String[] vertexs = {"A", "B", "C", "D", "E"};
//創建圖
Graph graph = new Graph(n);
//添加頂點
for (String vertex : vertexs) {
graph.insertVertex(vertex);
}
//連接頂點
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.showGraph();
}
//n為頂點的個數
public Graph(int n) {
edges = new int[n][n];
vertexList = new ArrayList<>(n);
numOfEdges = 0;
}
//插入頂點
public void insertVertex(String vertex) {
vertexList.add(vertex);
}
/**
* 添加邊
*
* @param v1 頂點在集合中存儲的下標
* @param v2 頂點在集合中的下標
* @param weight 兩個頂點之間的權值,0或者1,表示是否相連
*/
public void insertEdge(int v1, int v2, int weight) {
edges[v1][v2] = weight;
edges[v2][v1] = weight;
numOfEdges++;
}
//返回節點的個數
public int getNumOfVertex() {
return vertexList.size();
}
//返回邊的個數
public int getNumOfEdges() {
return numOfEdges;
}
//返回下標 i 對應的數
public String getValueByIndex(int i) {
return vertexList.get(i);
}
//返回v1和v2的權值
public int getWeigh(int v1, int v2) {
return edges[v1][v2];
}
//顯示矩陣
public void showGraph() {
for (int[] link : edges) {
System.out.println(Arrays.toString(link));
}
}
}