news 2026/5/11 0:38:18

图的表示以及基础操作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
图的表示以及基础操作

图其实有很多应用,现实系统可以用图来建模,相应的问题也可以约化为图计算问题。

图(graph)是一种非线性数据结构,由顶点(vertex)和边(edge)组成。我们可以将图
图G 抽象地表示为一组顶点V 和一组边E 的集合。

如果将顶点看作节点,将边看作连接各个节点的引用(指针),我们就可以将图看作一种从链表拓展而来的数据结构。相较于线性关系(链表)和分治关系(树),网络关系(图)的自由度更高,因而更为复杂。

图的表示
1,邻接矩阵
设图的顶点数量为 n ,邻接矩阵(adjacency matrix)使用一个 n乘以n大小的矩阵来表示图,每一行(列)代表一个顶点,矩阵元素代表边,用 1 或 0表示两个顶点之间是否存在边。设邻接矩阵为 M、顶点列表为 V ,那么矩阵元素 M[i,j]=1表示顶点 V[i]到顶点 V[j] 之间存在边,反之 M[i,j]=0表示两顶点之间无边。

顶点不能与自身相连,此时邻接矩阵主对角线元素没有意义。对于无向图,两个方向的边等价,此时邻接矩阵关于主对角线对称。将邻接矩阵的元素从 1 和 0替换为权重,则可表示有权图。使用邻接矩阵表示图时,我们可以直接访问矩阵元素以获取边,因此增删查改操作的效率很高,时间复杂度均为 O(1)。然而,矩阵的空间复杂度为O(n平方) ,内存占用较多。
基于邻接矩阵的基础操作

/* 基于邻接矩阵实现的无向图类 */classGraphAdjMat{List<Integer>vertices;// 顶点列表,元素代表“顶点值”,索引代表“顶点索引”List<List<Integer>>adjMat;// 邻接矩阵,行列索引对应“顶点索引”/* 构造方法 */publicGraphAdjMat(int[]vertices,int[][]edges){this.vertices=newArrayList<>();this.adjMat=newArrayList<>();// 添加顶点for(intval:vertices){addVertex(val);}// 添加边// 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引for(int[]e:edges){addEdge(e[0],e[1]);}}/* 获取顶点数量 */publicintsize(){returnvertices.size();}/* 添加顶点 */publicvoidaddVertex(intval){intn=size();// 向顶点列表中添加新顶点的值vertices.add(val);// 在邻接矩阵中添加一行List<Integer>newRow=newArrayList<>(n);for(intj=0;j<n;j++){newRow.add(0);}adjMat.add(newRow);// 在邻接矩阵中添加一列for(List<Integer>row:adjMat){row.add(0);}}/* 删除顶点 */publicvoidremoveVertex(intindex){if(index>=size())thrownewIndexOutOfBoundsException();// 在顶点列表中移除索引 index 的顶点vertices.remove(index);// 在邻接矩阵中删除索引 index 的行adjMat.remove(index);// 在邻接矩阵中删除索引 index 的列for(List<Integer>row:adjMat){row.remove(index);}}/* 添加边 */// 参数 i, j 对应 vertices 元素索引publicvoidaddEdge(inti,intj){// 索引越界与相等处理if(i<0||j<0||i>=size()||j>=size()||i==j)thrownewIndexOutOfBoundsException();// 在无向图中,邻接矩阵关于主对角线对称,即满足 (i, j) == (j, i)adjMat.get(i).set(j,1);adjMat.get(j).set(i,1);}/* 删除边 */// 参数 i, j 对应 vertices 元素索引publicvoidremoveEdge(inti,intj){// 索引越界与相等处理if(i<0||j<0||i>=size()||j>=size()||i==j)thrownewIndexOutOfBoundsException();adjMat.get(i).set(j,0);adjMat.get(j).set(i,0);}/* 打印邻接矩阵 */publicvoidprint(){System.out.print("顶点列表 = ");System.out.println(vertices);System.out.println("邻接矩阵 =");PrintUtil.printMatrix(adjMat);}}

邻接表(adjacency list)使用 n个链表来表示图,链表节点表示顶点。第 i个链表对应顶点 i,其中存储了该顶点的所有邻接顶点(与该顶点相连的顶点)。

邻接表仅存储实际存在的边,而边的总数通常远小于 ,因此它更加节省空间。然而,在邻接表中需要通过遍历链表来查找边,因此其时间效率不如邻接矩阵。
基于邻接表的基础操作

/* 基于邻接表实现的无向图类 */classGraphAdjList{// 邻接表,key:顶点,value:该顶点的所有邻接顶点Map<Vertex,List<Vertex>>adjList;/* 构造方法 */publicGraphAdjList(Vertex[][]edges){this.adjList=newHashMap<>();// 添加所有顶点和边for(Vertex[]edge:edges){addVertex(edge[0]);addVertex(edge[1]);addEdge(edge[0],edge[1]);}}/* 获取顶点数量 */publicintsize(){returnadjList.size();}/* 添加边 */publicvoidaddEdge(Vertexvet1,Vertexvet2){if(!adjList.containsKey(vet1)||!adjList.containsKey(vet2)||vet1==vet2)thrownewIllegalArgumentException();// 添加边 vet1 - vet2adjList.get(vet1).add(vet2);adjList.get(vet2).add(vet1);}/* 删除边 */publicvoidremoveEdge(Vertexvet1,Vertexvet2){if(!adjList.containsKey(vet1)||!adjList.containsKey(vet2)||vet1==vet2)thrownewIllegalArgumentException();// 删除边 vet1 - vet2adjList.get(vet1).remove(vet2);adjList.get(vet2).remove(vet1);}/* 添加顶点 */publicvoidaddVertex(Vertexvet){if(adjList.containsKey(vet))return;// 在邻接表中添加一个新链表adjList.put(vet,newArrayList<>());}/* 删除顶点 */publicvoidremoveVertex(Vertexvet){if(!adjList.containsKey(vet))thrownewIllegalArgumentException();// 在邻接表中删除顶点 vet 对应的链表adjList.remove(vet);// 遍历其他顶点的链表,删除所有包含 vet 的边for(List<Vertex>list:adjList.values()){list.remove(vet);}}/* 打印邻接表 */publicvoidprint(){System.out.println("邻接表 =");for(Map.Entry<Vertex,List<Vertex>>pair:adjList.entrySet()){List<Integer>tmp=newArrayList<>();for(Vertexvertex:pair.getValue())tmp.add(vertex.val);System.out.println(pair.getKey().val+": "+tmp+",");}}}```
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 2:32:00

可控硅驱动光耦:工业控制的隐形守护者

在工业自动化的精密脉络中&#xff0c;信号传输的稳定性与安全性如同设备的神经中枢&#xff0c;一旦受到干扰或破坏&#xff0c;可能引发生产停滞甚至安全事故。可控硅驱动光耦作为工业控制领域的核心元件&#xff0c;凭借其独特的光电隔离技术与卓越的抗干扰性能&#xff0c;…

作者头像 李华
网站建设 2026/5/10 6:41:31

终极Node.js版本管理指南:3步快速安装配置nvm-desktop

在现代Web开发中&#xff0c;Node.js版本管理是每个开发者必须面对的重要课题。nvm-desktop作为一款功能强大的桌面应用程序&#xff0c;专门为Node.js开发者设计&#xff0c;能够高效管理多个Node.js版本。无论你是前端工程师、后端开发者还是全栈程序员&#xff0c;这款工具都…

作者头像 李华
网站建设 2026/5/9 2:38:32

Zabbix 6 与 PHP 5 版本**完全不兼容

Zabbix 6 与 PHP 5 版本完全不兼容&#xff0c;强行匹配会导致 Zabbix 前端无法正常运行&#xff0c;甚至出现严重的功能异常或报错&#xff0c;具体表现和原因如下&#xff1a; 一、直接结果&#xff1a;Zabbix 前端无法启动/运行 Zabbix 6 对 PHP 的最低要求是 PHP 7.2&#…

作者头像 李华
网站建设 2026/5/9 2:34:04

企业微信“群机器人”消息推送的限制与绕过思路技术分析

一、引言 (Introduction) 1.1 背景&#xff1a; 企业微信群机器人是应用快速推送通知到群聊的官方、便捷方式。然而&#xff0c;在外部客户群和个性化营销场景下&#xff0c;其功能限制明显。 1.2 目的&#xff1a; 深入分析企业微信群机器人消息推送的技术限制&#xff0c;并…

作者头像 李华
网站建设 2026/5/9 2:21:29

LocalAI终极部署手册:3分钟快速搭建本地AI服务平台

LocalAI终极部署手册&#xff1a;3分钟快速搭建本地AI服务平台 【免费下载链接】LocalAI 项目地址: https://gitcode.com/gh_mirrors/loc/LocalAI 还在为云端AI服务的高昂费用和隐私担忧而烦恼吗&#xff1f;&#x1f914; LocalAI为您带来了革命性的本地AI解决方案&am…

作者头像 李华
网站建设 2026/5/9 2:21:40

今日校园自动化工具终极指南:轻松实现校园任务智能管理

今日校园自动化工具是一款基于Python开发的智能校园管理助手&#xff0c;专为解放学生和教师的重复性工作而设计。通过自动化处理签到、数据整理、查寝等日常任务&#xff0c;帮助用户大幅提升校园工作效率&#xff0c;实现智能化的校园生活管理。 【免费下载链接】auto-cpdail…

作者头像 李华