摘要

实现图结构的方案大致为邻接矩阵和邻接表,本期就介绍一下这两个方案分别是什么。在最后会处理一下图的基本接口,以及顶点结构和边结构,为下期代码实现做准备。

前两期文章介绍了图的基本概念,以及图的种类。这期就了解一下实现图结构的方案。主要有两种实现方案,分别是邻接矩阵邻接表

邻接矩阵

邻接矩阵就是用数组来分别存放顶点和边。即用一个一维数组存放顶点,用一个二维数组存放边。

上图可以看出,使用邻接矩阵描述一个无向图时,若两个顶点连接,就设置为 1,反之,就设置为 0。

那么有向图,该怎么表示呢?

上图可以看到,有向图的邻接矩阵从左侧看,分别可以知道某一个顶点到其他顶点的连接情况,比如顶点 v1 和顶点 v3 的连接情况,就可以看到左侧 v1 和顶部 v3 的交汇点数字为 1,左侧 v3 和顶部 v1 的交汇点数字为 1,这就表示图中 v1 和 v3 相关连接的关系。

最后就是有权图该如何表示呢?

有权图的邻接矩阵和有向图的邻接矩阵很相似,有两个区别点:

  1. 当一个顶点到另外一个顶点有连接,交汇的点填写权值;

  2. 那么这个顶点到另外一个顶点没有连接,交汇点填写 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项;

  • 顶点的结构中要分别记录出度和入度的边,以及元素;

  • 边的结构中要分别记录起始顶点和结束顶点;

  • 不论是顶点结构还是边结构,都要重写 equalshashCode 这两个方法。

数据结构与算法-进阶(五)图的实现相关推荐

  1. 数据结构和算法(五)--栈(Stack)

    数据结构和算法(五)–栈(Stack) 什么是栈 栈是一种特殊的线性表,只能在一端进行操作 往栈中添加元素,一般叫做push,入栈 往栈中移除元素,一般叫做pop,弹栈/出栈(只能移除栈顶元素) 栈遵 ...

  2. 数据结构与算法思维导图(学习笔记)

    版本 数据结构与算法思维导图V1.0 V1.0分享版本这个可以直接看,不需要下载. 说明 1.free 2.目前内容主要包含内容包含: 数据结构与算法思维导图 包含:线性表.顺序结构.链式结构,栈与队 ...

  3. 数据结构与算法学习笔记——图 C++实现

    数据结构与算法学习笔记--图 C++实现 1 概念 2 图的表示方法 3 算法 3.1 拓扑排序 3.2 图的搜索算法 3.2.1 广度优先搜索(BFS) 3.2.2 深度优先搜索(DFS) 3.3 ...

  4. 数据结构和算法 -- 学习导图

    数据结构和算法 是作为程序员写出高效代码的基础,为了今后的两年在高效代码之路上持续精进,将按照此学习导图进行 算法和数据结构的刻意练习,同时也希望为同样有高效代码追求的伙伴们提供一条学习路径,共同进步 ...

  5. 数据结构与算法思维导图(目录)

    (小甲鱼)数据结构与算法(全99讲完结版)学习刷完纪念. 下面是总结的学习内容思维导图.

  6. 数据结构与算法(五)排序算法篇

    排序算法篇 恭喜各位小伙伴来到最后一部分:排序算法篇,数据结构与算法的学习也接近尾声了,坚持就是胜利啊! 一个数组中的数据原本是凌乱的,但是由于需要,我们需要使其有序排列,要实现对数组进行排序我们之前 ...

  7. python中判断无向图是否有环_数据结构与算法:17 图

    17 图 知识结构: 图1 知识结构 1. 图的基本概念与术语 1.1 图的定义 图由顶点集和边集组成,记为 . 顶点集:顶点的有穷非空集合,记为. 边集:顶点偶对的有穷集合,记为 . 边: 无向边: ...

  8. 数据结构与算法(五)图

    基础知识: 一.图的存储 1.十字链表 十字链表是邻接表和逆邻接表的结合,能够由firstinarc出发得到vi的整个邻接表,由firstoutarc出发得到vi的整个逆邻接表.构建的方法就是每读入一 ...

  9. 数据结构与算法 -- 树结构与图结构

    树的概念 形式化定义:算法的集合树(Tree)是由一个或多个结点组成的有限集合T,其中有一个特定的称为根的结点:其余结点可分为(m≥0)个互不相交的有限集T1,T2,T3,-,Tm,每一个集合本身又是 ...

  10. 数据结构与算法09 之图

    在计算机程序设计中,图是最常用的结构之一.图是一种与树有些相像的数据结构,实际上,从数学意义上说,树是图的一种.然而在计算机程序设计中,图的应用方式与树不同. 前面讨论的数据结构都有一个框架,这个框架 ...

最新文章

  1. linux一键安装包
  2. 正则严格验证身份证信息
  3. ORA-16629: database reports a different protection
  4. java求最小步数,使数组值相等的最小步数 Minimum Moves to Equal Array Elements
  5. Winform中导出Excel数据量百万级的处理办法-导出为csv文件
  6. oracle放在内存里,oracle如中何把小表钉住在内存中
  7. 理解setState(),异步还是同步?
  8. 国漫《大闹天宫》4K修复版上线西瓜视频、鲜时光
  9. 【回放视频+PPT下载整理】Elasticsearch Meetup系列第二期
  10. 玩玩Linux云主机-安装MySQL ,The server quit without updating PID file,Linux chown 权限管理
  11. 项目管理常用文档表格模板二
  12. 对六自由度机械臂的运动控制及python实现(附源码)
  13. X509证书基本概念
  14. AI英雄出少年!奔赴星辰,他们正在创造黄金时代
  15. Excel计算傅里叶变化FFT
  16. docx行间距怎么设置_Word如何调整字间距,行间距.docx
  17. 席南华院士:数学的意义
  18. Layui 数据表格toolbar中使用模板引擎templet,当前系统时间比较问题
  19. 基于NVIDIA TX2的usb basyer工业相机编码推流
  20. Android Notification的完整例子--设置下班闹钟和护眼闹钟

热门文章

  1. 3.深入了解listen函数
  2. java为什么是静态的_为什么此方法必须是静态的(Java)?
  3. ​力扣解法汇总904.水果成篮
  4. 通过注册表实现程序开机自启动的方法
  5. 我国计算机发展历程简述,简述计算机的发展历程??
  6. SQL笔面试题:如何求取中位数?
  7. 极客云原生营-云原生知识
  8. 中国目前拥有的人造卫星的种类及其作用
  9. 量化投资学习——介绍orderflow
  10. 布谷鸟哈希函数的参数_CuckooHash(布谷鸟散列)