0110符号图-无向图-数据结构和算法(Java)
创始人
2025-05-28 02:02:42
0

文章目录

    • 1 概述
    • 2 API
    • 3 实现
    • 4 测试
    • 5 间隔度数
    • 后记

1 概述

在典型应用中,图都是通过文件或者网页定义的,使用的是字符串而非整数来表示和指代顶点。为了适应这样的应用,我们定义了拥有一下性质的格式:

  • 顶点名为字符串;
  • 用指定的分隔符来隔开顶点;
  • 每一行都表示一组边的集合,每一条边都连接着这一行的第一个名称表示的顶点和其他名称所表示的顶点;
  • 顶点总数V和边的总数E都是隐式定义的。

图1-1如下所示:在这里插入图片描述

该图表示一个小型运输系统模型,其中每个顶点是美国机场的代码,连接它们的边则表示顶点之间的航线。

图1-2如下所示:

在这里插入图片描述

上图为互联网电影数据库,文件每一行列出了一个电影名以及出演该部电影的一系列演员。电影和演员都是顶点,而邻接表中的每一条边都将电影和它的表演者联系起来,这是一副二分图。

2 API

public classSymbolGraph
SymbolGraph(String filename, String delm)根据filename指定的文件构造图,使用delm分隔顶点
public booleancontains(String key)key是一个顶点吗
intindexOf(String key)key的索引
public StringnameOf(int v)索引v的顶点名
GraphG()隐藏的Graph对象

3 实现

package com.gaogzhen.datastructure.graph.undirected;import edu.princeton.cs.algs4.Graph;
import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.ST;/*** 符号图* @author: Administrator* @createTime: 2023/03/14 19:59*/
public class SymbolGraph {/*** 符号表* 符号名-索引*/private ST st;/*** 反向索引数组* 索引->符号名*/private String[] keys;/*** 无向图*/private Graph graph;/*** 文件读入数据构建无向图* @param filename  文件路径* @param delimiter 顶点分隔符*/public SymbolGraph(String filename, String delimiter) {// 构建符号表st = new ST<>();In in = new In(filename);while (!in.isEmpty()) {String[] s = in.readLine().split(delimiter);for (int i = 0; i < s.length; i++) {if (!st.contains(s[i])) {st.put(s[i], st.size());}}}// 初始化反向索引数组keyskeys = new String[st.size()];for (String name : st.keys()) {keys[st.get(name)] = name;}// 构建无向图graph = new Graph(st.size());in = new In(filename);while (in.hasNextLine()) {String[] a = in.readLine().split(delimiter);int v = st.get(a[0]);for (int i = 1; i < a.length; i++) {int w = st.get(a[i]);graph.addEdge(v, w);}}}/*** 是否包含某个顶点* @param s   给定顶点* @return {@code true} 如果顶点 {@code s}在符号表中;否则 {@code false}*/public boolean contains(String s) { return st.contains(s);}/*** 返回顶点名称对应的索引* @param s 顶点名称* @return 顶点名称 {@code s} 对应的索引(0~V-1)*/public int indexOf(String s) {return st.get(s);}/*** 返回索引{@code v}对应的顶点名称* @param v 顶点索引(0~V-1)* @return  索引 {@code v} 对应的顶点名称*/public String nameOf(int v) {validateVertex(v);return keys[v];}/*** 返回该符号图关联的无向图* @return  该符号图关联的无向图*/public Graph graph() {return graph;}/*** 校验顶点 {@code v} 是否合法* @param v 顶点v*/private void validateVertex(int v) {int c = graph.V();if (v < 0 || v >= c) {throw new IllegalArgumentException("顶点 " + v + " 不在 0~" + (c - 1) + " 之间");}}
}

符号表实现用到以下三种数据结构:

  • 符号表st,键的类型为String(顶点名),值的类型为Integer(索引);
  • 一个数组keys[],用做反向索引,保存每个顶点索引对应的顶点名称;
  • 一个Graph对象graph,它使用索引表示定的名称。

SymbolGraph会遍历2遍数据来构建上述数据结构。因为key[]和graph初始化需要用到顶点总数V,所以第一遍先构建符号表st,通过st.size()获取顶点总数。

典型应用中,不方便指定顶点总数V和边总数E,使用SymbolGraph方便在文件中增减数据。

4 测试

测试代码:

public static void testSymbolGraph() {SymbolGraph symbolGraph = new SymbolGraph("H:\\gaogzhen\\java\\projects\\algorithm\\asserts\\routes.txt", " ");System.out.println(symbolGraph.contains("ORD"));System.out.println(symbolGraph.indexOf("ORD"));System.out.println(symbolGraph.nameOf(3));System.out.println(symbolGraph.graph());
}

测试结果:

true
2
DEN
10 vertices, 18 edges 
0: 2 7 1 
1: 4 7 0 
2: 7 0 6 5 4 3 
3: 9 6 2 
4: 1 5 7 2 
5: 4 2 6 
6: 9 8 3 2 5 
7: 1 2 4 0 
8: 9 6 
9: 6 8 3 

演员电影图自己测试。

5 间隔度数

图处理一个经典问题就是,找到一个社交网络中两个人间隔的度数。以电影-演员图为例,kevin Bacon是一个活跃演员,演过很多电影,找出演员Kevin Bacon数。Kevin Bacon数:Bacon本人为0,所有和Bacon演过同一部电影的人的值为1,所有(除了Kevin Bacon)和Kevin Bacon数为1的演员演过同一部电影的其他演员值为2,依次类推。

实现代码:

package com.gaogzhen.datastructure.graph.undirected;import edu.princeton.cs.algs4.StdIn;/*** 无向图间隔度数* @author: Administrator* @createTime: 2023/03/14 21:17*/
public class DegreesOfSeparation {public static void degreesOfSeparation(String filename, String delimiter, String source) {// 构建符号图SymbolGraph symbolGraph = new SymbolGraph(filename, delimiter);if (!symbolGraph.contains(source)) {System.out.println(source + " 不在数据库中");return;}// 符号图和起始顶点构建最短路径BreadthFirstDirectedPaths bfs = new BreadthFirstDirectedPaths(symbolGraph.graph(), symbolGraph.indexOf(source));while (!StdIn.isEmpty()) {String sink = StdIn.readLine();if (symbolGraph.contains(sink)) {int s = symbolGraph.indexOf(sink);if (bfs.hasPathTo(s)) {for (Integer v : bfs.pathTo(s)) {System.out.println("\t" + symbolGraph.nameOf(v));}} else {System.out.println(sink + " 与 " + source + " 不相连");}} else {System.out.println(sink + " 不在数据库中");}}}
}

测试代码:

    public static void testDegreesOfSeparate() {String filename = "H:\\gaogzhen\\java\\projects\\algorithm\\asserts\\movies.txt";String delimiter = "/";String source = "Bacon, Kevin";DegreesOfSeparation.degreesOfSeparation(filename, delimiter, source);}

测试结果:

xxx
xxx 不在数据库中
Kidman, NicoleBacon, KevinJFK (1991)Sutherland, Donald (I)Cold Mountain (2003)Kidman, Nicole
Aronson, SteveBacon, KevinJFK (1991)X, MalcolmMalcolm X (1992)Aronson, Steve

间隔度数的理论在计算机网络的设计以及理解各个科学领域中的自然网络中都能起到重要的作用。

后记

如果小伙伴什么问题或者指教,欢迎交流。

❓QQ:806797785

⭐️源代码仓库地址:https://gitee.com/gaogzhen/algorithm

参考链接:

[1][美]Robert Sedgewich,[美]Kevin Wayne著;谢路云译.算法:第4版[M].北京:人民邮电出版社,2012.10.p352-356.

相关内容

热门资讯

腌制美味脆爽酸辣白萝卜,解锁冬... 在寒风凛冽的冬日里,一道酸辣脆爽的白萝卜小菜,无疑能为餐桌增添一抹亮色,温暖人心。今天,作为你们的美...
福建人私藏的 10 家小吃店,... 福建美食藏龙卧虎,本地人私藏的 10 家小吃店更是美味的宝藏。从让外地人改观的土笋冻,到令人垂涎的蚵...
老公从挑食到光盘的8道家常菜,... #图文打卡计划# 结婚五年才发现,老公挑食的毛病不是治不好——是没遇上能镇住味蕾的"硬菜"!从干椒葱...
冬日里的温暖滋味:白菜香菇胡萝... 在寒风凛冽的冬日里,每个人都渴望一份温暖而美味的慰藉。忙碌的生活节奏和不断累积的压力,让人们的身体容...
“老干妈”的传奇之路:从路边摊... 在美食的世界里,有一种味道,它不仅仅是一种调味品,更是一种情感的寄托,一种文化的传承。这种味道,就是...
暴吵萌厨新手攻略,厨神必学技巧 还在被顾客催单催到手忙脚乱?别慌!专为厨房小白设计,用最接地气的操作和最野的套路,鸟人云教你化身厨房...
原创 四... 四川,这座被誉为"天府之国"的旅游文化名城,更是享誉全球的"美食天堂"。作为中国传统"四大菜系"之一...
山东日照:茶香漫青山 绿意生金... 5月23日,位于日照市岚山区碑廓镇的浏园春有机茶园。 山东省日照市岚山区在“南茶北引”试种成功的基础...
德州扒鸡的 “摇滚新生”甜辣鸡... 本文聚焦德州扒鸡推出的 “摇滚新生” 甜辣鸡爪与音乐节跨界合作这一创新现象。通过剖析其将非遗美食与现...
端午将至,没有一个人能空手从贵... 端午节的脚步渐近 贵阳市文笔街的空气中 已弥漫着粽叶与糯米的清香 这条不足百米的街巷 因聚集十余家 ...
NTT计算实例by ChatG... 假设我们要计算多项式 f(x) = x^3 + 2x^2 + x +...
河南景区招帅哥NPC月薪开到3... 01.盒马卖含褪黑素的晚安牛奶 02.乐高推出福尔摩斯贝克街图书角 03.星巴克招聘飞行员年薪最高3...
听说你端午节想出去玩?注意!这... 端午假期马上就要到了 很多人做好了出游计划 乐逛景区,安全第一 近日,文化和旅游部组织多个暗访小组对...
java Vector 源码分... Vector类的底层实现Vector类 VS ArrayList类Vector类源码解读无参构造——...
露营经济崛起:如何精明选购露营... 近年来,露营经济持续升温,从城市周边到深山野林,露营已成为都市人亲近自然、放松身心的热门选择,而设备...
五一假期户外游玩这份防虫指南能... 怎么说呢,每年一到小长假,朋友圈就被各种美景照片刷屏。但你可能不知道,那些看似岁月静好的九宫格背后,...
基于微信小程序的图书馆座位预约... 1. 系统开发背景 图书馆因有良好的学习氛围、大量的学习资源吸引大家前来学习,图书馆还...