数据结构与算法-进阶(五)图的实现
摘要
实现图结构的方案大致为邻接矩阵和邻接表,本期就介绍一下这两个方案分别是什么。在最后会处理一下图的基本接口,以及顶点结构和边结构,为下期代码实现做准备。
前两期文章介绍了图的基本概念,以及图的种类。这期就了解一下实现图结构的方案。主要有两种实现方案,分别是邻接矩阵和邻接表。
邻接矩阵
邻接矩阵就是用数组来分别存放顶点和边。即用一个一维数组存放顶点,用一个二维数组存放边。
上图可以看出,使用邻接矩阵描述一个无向图时,若两个顶点连接,就设置为 1,反之,就设置为 0。
那么有向图,该怎么表示呢?
上图可以看到,有向图的邻接矩阵从左侧看,分别可以知道某一个顶点到其他顶点的连接情况,比如顶点 v1 和顶点 v3 的连接情况,就可以看到左侧 v1 和顶部 v3 的交汇点数字为 1,左侧 v3 和顶部 v1 的交汇点数字为 1,这就表示图中 v1 和 v3 相关连接的关系。
最后就是有权图该如何表示呢?
有权图的邻接矩阵和有向图的邻接矩阵很相似,有两个区别点:
当一个顶点到另外一个顶点有连接,交汇的点填写权值;
那么这个顶点到另外一个顶点没有连接,交汇点填写 null(或者其他符合都可以)。
邻接表
邻接表就类似哈希表,即把所有顶点都依次放到一个数组里面,然后拿到第一个顶点,找到和它连接的顶点,像火车车厢一样,一个个的指向它们。直到最后一个没有可以指向的顶点时,就用 null 来表示(或者其他的符号)。
图中箭头指向,表示要将指向的顶点放在上一个空格的位置,接下来表示有向图时,如下图:
表示有权图时,可以将权值放在指向的下一个顶点中,如下图:
基础接口
接下来,就开始用代码来实现图结构。这里先定义一下图结构的接口 API,包括添加或者删除顶点,添加或者删除边等。
// 顶点数量
int verticesSize();
// 边数量
int edgesSize();// 添加顶点
void addVertice(V v);
// 移除顶点
void removeVertice(V v);// 添加边
void addEdge(V fromV, V toV);
// 添加边,包括权值
vode addEdge(V fromV, V toV, E weight);
// 移除边
void removeEdge(V fromV, V toV);
定义顶点
在开始之前,需要先了解出度和入度这两个名词:
出度:一个顶点的出度为 x,是指有 x 条边以这个顶点为起点;
入度:一个顶点的入度为 x,是指有 x 条边以该顶点为终点;
在一个顶点中需要记录出度的边,也要记录入度的边,因为顶点上有多个边,所以需要用列表结构来存储,还需要记录元素。自定义一个顶点比较的方法,来确定顶点是否相同。最后重写一下 获取顶点哈希值的方法,留作备用。
private static class Vertex<V, E> {V value;// 进来的边Set<Edge<V, E>> inEdges = new HashSet<>();// 出去的边Set<Edge<V, E>> outEdges = new HashSet<>();// 构造方法 Vertex(V v) {this.value = v;}// 自定义对比和 hash code@Overridepublic boolean equals(Object obj) {return Objects.equals(value, ((Vertex<V, E>)obj).value);}@Overridepublic int hashCode() {return value == null ? 0 : value.hashCode();}
}
定义边
边结构中要记录起始和结束的顶点,一个边只能有一个起始顶点和一个结束顶点,这里也要提前定义记录权值的属性。在结构中要重写是否相同的方法,重写边的哈希值留作后用。
private static class Edge<V, E> {// 起点Vertex<V, E> from;// 终点Vertex<V, E> to;// 权值E weight;Edge(Vertex<V, E> from, Vertex<V, E> to) {this.from = from;this.to = to;}EdgeInfo<V, E> info() {return new EdgeInfo<>(from.value, to.value, weight);}// 实现对比和 hash code@Overridepublic boolean equals(Object obj) {Edge<V, E> edge = (Edge<V,E>)obj;return Objects.equals(from, edge.from) && Objects.equals(to, edge.to);}@Overridepublic int hashCode() {return from.hashCode() * 31 + to.hashCode();}
}
代码中可以看出,在 equals
方法中,要同时满足起始顶点、结束顶点相等,这个边才相等。在 hashCode
中的 *31
是将起始顶点的哈希值放在高位(向左移动了5个位置,二进制),和结束顶点的哈希值组合得来的。
总结
图的两个实现方案分别是邻接矩阵和邻接表;
图的基本接口是顶点和边的数量,添加和删除顶点,添加和删除边,这3项;
顶点的结构中要分别记录出度和入度的边,以及元素;
边的结构中要分别记录起始顶点和结束顶点;
不论是顶点结构还是边结构,都要重写
equals
和hashCode
这两个方法。
数据结构与算法-进阶(五)图的实现相关推荐
- 数据结构和算法(五)--栈(Stack)
数据结构和算法(五)–栈(Stack) 什么是栈 栈是一种特殊的线性表,只能在一端进行操作 往栈中添加元素,一般叫做push,入栈 往栈中移除元素,一般叫做pop,弹栈/出栈(只能移除栈顶元素) 栈遵 ...
- 数据结构与算法思维导图(学习笔记)
版本 数据结构与算法思维导图V1.0 V1.0分享版本这个可以直接看,不需要下载. 说明 1.free 2.目前内容主要包含内容包含: 数据结构与算法思维导图 包含:线性表.顺序结构.链式结构,栈与队 ...
- 数据结构与算法学习笔记——图 C++实现
数据结构与算法学习笔记--图 C++实现 1 概念 2 图的表示方法 3 算法 3.1 拓扑排序 3.2 图的搜索算法 3.2.1 广度优先搜索(BFS) 3.2.2 深度优先搜索(DFS) 3.3 ...
- 数据结构和算法 -- 学习导图
数据结构和算法 是作为程序员写出高效代码的基础,为了今后的两年在高效代码之路上持续精进,将按照此学习导图进行 算法和数据结构的刻意练习,同时也希望为同样有高效代码追求的伙伴们提供一条学习路径,共同进步 ...
- 数据结构与算法思维导图(目录)
(小甲鱼)数据结构与算法(全99讲完结版)学习刷完纪念. 下面是总结的学习内容思维导图.
- 数据结构与算法(五)排序算法篇
排序算法篇 恭喜各位小伙伴来到最后一部分:排序算法篇,数据结构与算法的学习也接近尾声了,坚持就是胜利啊! 一个数组中的数据原本是凌乱的,但是由于需要,我们需要使其有序排列,要实现对数组进行排序我们之前 ...
- python中判断无向图是否有环_数据结构与算法:17 图
17 图 知识结构: 图1 知识结构 1. 图的基本概念与术语 1.1 图的定义 图由顶点集和边集组成,记为 . 顶点集:顶点的有穷非空集合,记为. 边集:顶点偶对的有穷集合,记为 . 边: 无向边: ...
- 数据结构与算法(五)图
基础知识: 一.图的存储 1.十字链表 十字链表是邻接表和逆邻接表的结合,能够由firstinarc出发得到vi的整个邻接表,由firstoutarc出发得到vi的整个逆邻接表.构建的方法就是每读入一 ...
- 数据结构与算法 -- 树结构与图结构
树的概念 形式化定义:算法的集合树(Tree)是由一个或多个结点组成的有限集合T,其中有一个特定的称为根的结点:其余结点可分为(m≥0)个互不相交的有限集T1,T2,T3,-,Tm,每一个集合本身又是 ...
- 数据结构与算法09 之图
在计算机程序设计中,图是最常用的结构之一.图是一种与树有些相像的数据结构,实际上,从数学意义上说,树是图的一种.然而在计算机程序设计中,图的应用方式与树不同. 前面讨论的数据结构都有一个框架,这个框架 ...
最新文章
- linux一键安装包
- 正则严格验证身份证信息
- ORA-16629: database reports a different protection
- java求最小步数,使数组值相等的最小步数 Minimum Moves to Equal Array Elements
- Winform中导出Excel数据量百万级的处理办法-导出为csv文件
- oracle放在内存里,oracle如中何把小表钉住在内存中
- 理解setState(),异步还是同步?
- 国漫《大闹天宫》4K修复版上线西瓜视频、鲜时光
- 【回放视频+PPT下载整理】Elasticsearch Meetup系列第二期
- 玩玩Linux云主机-安装MySQL ,The server quit without updating PID file,Linux chown 权限管理
- 项目管理常用文档表格模板二
- 对六自由度机械臂的运动控制及python实现(附源码)
- X509证书基本概念
- AI英雄出少年!奔赴星辰,他们正在创造黄金时代
- Excel计算傅里叶变化FFT
- docx行间距怎么设置_Word如何调整字间距,行间距.docx
- 席南华院士:数学的意义
- Layui 数据表格toolbar中使用模板引擎templet,当前系统时间比较问题
- 基于NVIDIA TX2的usb basyer工业相机编码推流
- Android Notification的完整例子--设置下班闹钟和护眼闹钟