| 图是一种数据结构,其中结点可以具有零个或多个相邻元素。两个结点之间的连接称为边。 结点也可以称为顶点 |


| 无向图: 顶点之间的连接没有方向,比如A-B, 即可以是 A-> B 也可以 B->A |
| 路径: 比如从 D -> C 的路径有 |
| 1) D->B->C |
| 2) D->A->B->C |
-
有向图

-
带权图:边带权值的图

-
邻接矩阵
| 邻接矩阵是表示图形中顶点之间相邻关系的矩阵,对于n个顶点的图而言,矩阵是的row和col表示的是1....n个点 |
| |
| 矩阵最左边和最上边表示图的节点 |
| 矩阵种0表示无连接,1表示有连接 |

| 邻接矩阵需要为每个顶点都分配n个边的空间,其实有很多边都是不存在,会造成空间的一定损失. |
| 邻接表的实现只关心存在的边,不关心不存在的边。因此没有空间浪费,邻接表由数组+链表组成 |
| |
| 标号为0的结点的相关联的结点为 1 2 3 4, |
| 标号为1的结点的相关联结点为0 4, |
| 标号为2的结点相关联的结点为 0 4 5 |

| public class Graph { |
| |
| public static void main(String[] args) { |
| |
| int n = 8; |
| |
| String Vertexs[] = {"1", "2", "3", "4", "5", "6", "7", "8"}; |
| |
| |
| 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(); |
| } |
| |
| private ArrayList<String> vertexList; |
| private int[][] edges; |
| private int numOfEdges; |
| |
| |
| public Graph(int n) { |
| |
| edges = new int[n][n]; |
| vertexList = new ArrayList<String>(n); |
| numOfEdges = 0; |
| } |
| |
| |
| |
| public int getNumOfVertex() { |
| return vertexList.size(); |
| } |
| |
| |
| public int getNumOfEdges() { |
| return numOfEdges; |
| } |
| |
| |
| public void showGraph() { |
| for(int[] link : edges) { |
| System.err.println(Arrays.toString(link)); |
| } |
| } |
| |
| |
| public String getValueByIndex(int i) { |
| return vertexList.get(i); |
| } |
| |
| |
| public int getWeight(int v1, int v2) { |
| return edges[v1][v2]; |
| } |
| |
| |
| public void insertVertex(String vertex) { |
| vertexList.add(vertex); |
| } |
| |
| |
| |
| |
| |
| |
| |
| public void insertEdge(int v1, int v2, int weight) { |
| edges[v1][v2] = weight; |
| edges[v2][v1] = weight; |
| numOfEdges++; |
| } |
| |
| } |
-
深度优先

-
应用实例

-
具体步骤
| A到B,B到C是连通的,C到D没有连通,从B到D连通,D到E没有连通,从B到E连通 |

| |
| private boolean[] isVisited; |
| |
| |
| public Graph(int n) { |
| |
| edges = new int[n][n]; |
| vertexList = new ArrayList<String>(n); |
| numOfEdges = 0; |
| |
| } |
| |
| |
| |
| |
| |
| |
| public int getFirstNeighbor(int index) { |
| for(int j = 0; j < vertexList.size(); j++) { |
| if(edges[index][j] > 0) { |
| return j; |
| } |
| } |
| return -1; |
| } |
| |
| |
| public int getNextNeighbor(int v1, int v2) { |
| for(int j = v2 + 1; j < vertexList.size(); j++) { |
| if(edges[v1][j] > 0) { |
| return j; |
| } |
| } |
| return -1; |
| } |
| |
| |
| |
| private void dfs(boolean[] isVisited, int i) { |
| |
| System.out.print(getValueByIndex(i) + "->"); |
| |
| isVisited[i] = true; |
| |
| int w = getFirstNeighbor(i); |
| while(w != -1) { |
| if(!isVisited[w]) { |
| dfs(isVisited, w); |
| } |
| |
| w = getNextNeighbor(i, w); |
| } |
| } |
| |
| |
| public void dfs() { |
| isVisited = new boolean[vertexList.size()]; |
| |
| for(int i = 0; i < getNumOfVertex(); i++) { |
| if(!isVisited[i]) { |
| dfs(isVisited, i); |
| } |
| } |
| } |
| |
| # 测试 |
| System.out.println("深度遍历"); |
| graph.dfs(); |
-
广度优先

-
应用实例
| A到B |
| A到C |
| A不能连通D,从B到D |
| A不能连通E,从B到E |

| |
| private void bfs(boolean[] isVisited, int i) { |
| int u ; |
| int w ; |
| |
| LinkedList queue = new LinkedList(); |
| |
| System.out.print(getValueByIndex(i) + "=>"); |
| |
| isVisited[i] = true; |
| |
| queue.addLast(i); |
| while( !queue.isEmpty()) { |
| |
| u = (Integer)queue.removeFirst(); |
| |
| w = getFirstNeighbor(u); |
| while(w != -1) { |
| |
| if(!isVisited[w]) { |
| System.out.print(getValueByIndex(w) + "=>"); |
| |
| isVisited[w] = true; |
| |
| queue.addLast(w); |
| } |
| |
| w = getNextNeighbor(u, w); |
| } |
| } |
| } |
| |
| |
| public void bfs() { |
| isVisited = new boolean[vertexList.size()]; |
| for(int i = 0; i < getNumOfVertex(); i++) { |
| if(!isVisited[i]) { |
| bfs(isVisited, i); |
| } |
| } |
| } |
| |
| # 测试 |
| System.out.println("广度优先!"); |
| graph.bfs(); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术