数据结构与算法--符号图

为了计算简单,传统的图中,都是使用整数来表示顶点,这样难免会有点抽象,不能直接反映各个顶点代表的信息。在实际生活中,使用图时一般会建立一个一一对应的关系表,如下

顶点 0 1 2
信息 北京 上海 深圳

图的处理过程中,比如说到处理顶点2,可能要去查看上表,才能知道说的是“深圳”。在典型的应用中,图都是通过文件或者网页定义的,更多的是用字符串而非整数,使用字符串能更加直观地反映各个顶点的信息。为了使得通过字符串能快速找到对应的顶点,会用到符号表进行查找,与图结合起来,这种数据结构被称为符号图

对于符号图的定义,有如下约定:

  • 顶点名是字符串
  • 输入中的每一行表示一组边的集合,每一行的第一个顶点和该行之后的所有顶点都相连。比如下面这个二维数组,里面每一个一维数组都是一组边的集合,一维数组中第一个顶点(如“产品D”),和其后的每一个顶点都相连(如与“产品D”对应的"经销商1",和"经销商6")
String[][] edges = {{"产品A", "经销商1", "经销商3", "经销商4", "经销商6"},{"产品B", "经销商1", "经销商2", "经销商3", "经销商5", "经销商6"},{"产品C", "经销商1", "经销商3", "经销商4", "经销商5", "经销商6"},{"产品D, "经销商1", "经销商6"}};

符号图的核心还是图,内部数据结构中顶点还是用整数表示。只不过里面加入了符号表的功能,使得整数顶点和字符串形成映射,可以方便地:

  • 通过整数索引,查找对应的字符串
  • 通过字符串,查找对应的顶点(整数表示)

基于此,实现符号图如下。

package Chap7;import Chap8.BST;public class SymbolUnDiGraph {// 键是顶点字符串,值是顶点private BST<String, Integer> st; // 符号名 -> 顶点索引private String[] keys; // 顶点索引 -> 符号名private UndiGraph<String> graph;public SymbolUnDiGraph(String[][] edges) {// 第一次遍历边集,建立符号表st = new BST<>();for (String[] infos : edges) {for (String info : infos) {// 重复的字符串不再分配顶点if (!st.contains(info)) {st.put(info, st.size());}}}keys = new String[st.size()];for (String name : st.keys()) {keys[st.get(name)] = name;}// 第二次遍历边集// 构造图, 每一行的第一个顶点和该行的其他顶点相连graph = new UndiGraph<>(st.size());for (String[] infos : edges) {int v = st.get(infos[0]);for (int i = 1; i < infos.length; i++) {graph.addEdge(v, st.get(infos[i]));}}}public boolean contains(String name) {return st.contains(name);}public int indexOf(String name) {return st.get(name);}public String nameOf(int v) {return keys[v];}public UndiGraph<String> graph() {return graph;}public static void main(String[] args) {String[][] edges = {{"产品A", "经销商1", "经销商3", "经销商4", "经销商6"},{"产品B", "经销商1", "经销商2", "经销商3", "经销商5", "经销商6"},{"产品C", "经销商1", "经销商3", "经销商4", "经销商5", "经销商6"},{"产品D", "经销商1", "经销商6"}};SymbolUnDiGraph sg = new SymbolUnDiGraph(edges);UndiGraph<String> graph = sg.graph();System.out.println("经销商4有经营下面几种产品");for (int w : graph.adj(sg.indexOf("经销商4"))) {System.out.print(sg.nameOf(w) + " ");}System.out.println();System.out.println("产品C在下面几个经销商有售");for (int w : graph.adj(sg.indexOf("产品C"))) {System.out.print(sg.nameOf(w) + " ");}System.out.println();}
}

上面的代码会打印如下信息

经销商4有经营下面几种产品
产品A 产品C
产品C在下面几个经销商有售
经销商1 经销商3 经销商4 经销商5 经销商6 

符号表的实现采用基于二分查找的有序数组。即上面的BST<String, Integer> st,可以通过字符串快速找到与之对应的顶点,这通过indexOf(String name)实现;

另外建立了一个String[]数组,可以通过整数表示的顶点获取该顶点的信息,这通过nameOf(int v)实现。contains方法可以直接用字符串判断某个顶点是否在图中。graph方法返回边集合定义的无向图。

从上面的代码可以看出,我们全程没有和整数打交道,实际上这些工作内部的数据结构已经帮我们做好了。代码中总共两次遍历边集,第一次是构造符号表,建立了顶点和字符串的关系。核心是下面这句,他将每一个不重复的字符串都放入符号表,与之对应的整数顶点直接使用符号表的长度这个值。(比如第一个被放入符号表的顶点为0,以此类推。)

// 重复的字符串不再分配顶点
if (!st.contains(info)) {st.put(info, st.size());
}

之后通过反向索引得到String[] keys,下图清晰得剖析了符号图的数据结构

符号图当然可以处理有向图,只需将图的数据类型换成有向图即可,其余代码都不改变!

package Chap7;import Chap8.BST;/*** 针对有向图的符号图,使用字符串表示顶点*/
public class SymbolDiGraph {// 键是顶点字符串,值是顶点private BST<String, Integer> st; // 符号名 -> 顶点索引private String[] keys; // 顶点索引 -> 符号名private DiGraph<String> graph;public SymbolDiGraph(String[][] edges) {st = new BST<>();for (String[] infos : edges) {for (String info : infos) {// 重复的字符串不再分配顶点if (!st.contains(info)) {st.put(info, st.size());}}}keys = new String[st.size()];for (String name : st.keys()) {keys[st.get(name)] = name;}// 构造图, 每一行的第一个顶点和该行的其他顶点相连graph = new DiGraph<>(st.size());for (String[] infos : edges) {int v = st.get(infos[0]);for (int i = 1; i < infos.length; i++) {graph.addEdge(v, st.get(infos[i]));}}}public boolean contains(String name) {return st.contains(name);}public int indexOf(String name) {return st.get(name);}public String nameOf(int v) {return keys[v];}public DiGraph<String> graph() {return graph;}public static void main(String[] args) {String[][] edges = {{"郑州", "上海", "北京", "西安", "成都"},{"成都", "郑州", "北京", "西安"},{"上海", "北京"},{"西安", "成都", "郑州"}};SymbolDiGraph sg = new SymbolDiGraph(edges);DiGraph<String> graph = sg.graph();for (int w : graph.adj(sg.indexOf("西安"))) {System.out.print(sg.nameOf(w) + " ");}System.out.println();}
}

by @sunhaiyu

2017.11.12

转载于:https://www.cnblogs.com/sun-haiyu/p/7821329.html

数据结构与算法--符号图相关推荐

  1. python函数结构图_Python数据结构与算法之图结构(Graph)实例分析

    本文实例讲述了Python数据结构与算法之图结构(Graph).分享给大家供大家参考,具体如下: 图结构(Graph)--算法学中最强大的框架之一.树结构只是图的一种特殊情况. 如果我们可将自己的工作 ...

  2. python define graph_Python数据结构与算法之图结构(Graph)实例分析

    本文实例讲述了Python数据结构与算法之图结构(Graph).分享给大家供大家参考,具体如下: 图结构(Graph)--算法学中最强大的框架之一.树结构只是图的一种特殊情况. 如果我们可将自己的工作 ...

  3. python棋盘最短路径_Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例...

    本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...

  4. 特征图注意力_从数据结构到算法:图网络方法初探

    作者 | 朱梓豪 来源 | 机器之心 原文 | 从数据结构到算法:图网络方法初探 如果说 2019 年机器学习领域什么方向最火,那么必然有图神经网络的一席之地.其实早在很多年前,图神经网络就以图嵌入. ...

  5. 数据结构与算法之-----图(拓扑排序)

    [​​​​​​​ 写在前面的话:本专栏的主要内容:数据结构与算法. 1.对于​​​​​​​初识数据结构的小伙伴们,鉴于后面的数据结构的构建会使用到专栏前面的内容,包括具体数据结构的应用,所使用到的数据 ...

  6. 数据结构与算法之-----图(搜索算法)

    [ 写在前面的话:本专栏的主要内容:数据结构与算法. 1.对于​​​​​​​初识数据结构的小伙伴们,鉴于后面的数据结构的构建会使用到专栏前面的内容,包括具体数据结构的应用,所使用到的数据结构,也是自己 ...

  7. 数据结构与算法之图的应用

    数据结构与算法之图的应用 图的定义和基本概念 图的实现 数组〈邻接矩阵〉 邻接表 图的应用 最小生成树 Prim(普里姆)算法 Kruskal(克鲁斯卡尔)算法 最短路径 迪克斯特拉算法 拓扑排序 执 ...

  8. js数据结构和算法(8)-图

    8-图(第11章) 8.1 图的定义 图是一种非线性结构,由一系列顶点及其连接顶点的边组成.比如A和B.A和D是相邻的,而A和E不是相邻的.一个顶点相邻顶点的数量叫作度,比如A的度为3.D的度为4.路 ...

  9. 【数据结构与算法】图

    一:如何理解"图" 1,图和树一样都是非线性表数据结构,和树不同的是图是一种更加复杂的非线性表结构 2,树中的元素称之为节点,图中的元素则称之为顶点. 3,顶点可以与任意其他顶点建 ...

最新文章

  1. 红帽企业版Linux成为Linux下的.NET Core的参考平台
  2. NeurIPS 2018 | 如何用循环关系网络机智地解决数独类关系推理任务?
  3. MySQL数据库:游标Cursor
  4. MYSQL 与 Oracle 之间的数据类型转换
  5. mysql浅拷贝_List的复制 (浅拷贝与深拷贝)
  6. linux加密框架 crypto 算法管理 - 算法查找接口
  7. 【SpringMVC框架】springmvc入门程序-环境搭建
  8. 概率论符号_考研概率论知识点总结1
  9. mysql事务保证幂等_事务与一致性:刚性or柔性
  10. discuz uc_server 配置登录
  11. 视频会议、视频聊天、手机视频、跨平台视频如何开发之流程篇
  12. MKV文件提取dts音频转化成ac3
  13. C语言利用回调函数实现qsort函数
  14. Python告诉你NBA球星都喜欢在哪个位置出手?
  15. fastqc检验时不能执行java_fastqc出现错误
  16. Unity实用功能之读写Excel表格
  17. 陀螺财经:比特大陆与詹克团的“华为梦”
  18. 影像边缘提取源码_影像学和放射学为行业采用开放源码铺平了道路
  19. Java基础篇-基本类型
  20. Silverlight游戏研发手记:(五)SLG动感增效之《幻影粒子》

热门文章

  1. 怎么将aac转化为mp3?aac转mp3详细教程
  2. 超神学院中的引擎是生物计算机吗,超神学院:雄芯和乾坤就像一台计算机,前者是操作平台后者是CPU...
  3. CSS两个div并排
  4. maven仓库不支持cdh解决方案
  5. android逆向 registers,Android逆向——Android逆向进阶(3)
  6. idea安装Solidity插件
  7. 战争雷霆warthunder游戏内自定义文本mod的制作方法
  8. 【HCIP】数据链路层封装技术、GRE及实验(eNSP)
  9. 官方授权正版 ConceptDraw DIAGRAM 14、MINDMAP 12、OFFICE 7、 PROJECT 11 专业绘图项目管理软件套装
  10. 签了工作之后才发现,自己太草率了.....我看过的关于职业规划最好最全面的一篇文章 分类: 体会