为了便于理解,先抛出它的架构类图,在心目中有个大概的轮廓
graph类结构图
图论的解释
Guava
库的目录common.graph
包含的模块是一个描述实体(entity
)以及实体之间的关系的图数据结构模型库。例如:网页与超链接、科学家与他们写的论文、机场与其航线、人与其家族等。Guava-Graph
模块的目的是提供一种通用以及可扩展的语言来描述类似上述的举例。
定义(Definitions)
图中包含一组节点(node
)(也称为顶点)和一组连接节点的边(edge
)(也称为链接或者弧);边缘的节点我们称为端点(endpoint
)。(我们将在下文介绍一个叫Graph
的接口,我们将使用“图”来作为一般术语描述该数据结构,也可以使用它引用某个具体的图类型,即接口Graph
有很多具体的实现类)。
如果一条边定义了开始(source
)和结束(target
),这条边被城为有向边(directed
),否则称为无向边(undirected
)。有向边适用于非对称的关系模型(起源、指向、作者),而无向边适用于对称关系模型(折叠、距离、同级关系)。
图中每一条边都是有向边的,则被称为有向图;每一条边都是无向的,则被称为无向图。(common.graph
模块不支持图中既有有向边又有无向边的情形。)
举例:
graph.addEdge(nodeU, nodeV, edgeUV);
nodeU
和nodeV
是两个邻接点(adjacent
)。edgeUV
是顶点nodeU
到顶点nodeV
的事件(incident
)(反之亦然)
在有向图中,有如下定义:
nodeU
是nodeV
的一个前趋(predecessor
)nodeV
是nodeU
的一个后继(successor
)edgeUV
是nodeU
的一条出度(outgoing
)边edgeUV
是nodeV
的一条入度(incoming
)边nodeU
是边edgeUV
的起点(source
)nodeV
是边edgeUV
的终点(target
)
在无向图中,有如下定义:
nodeU
既是nodeV
的前趋也是nodeV
的后继nodeV
既是nodeU
的前趋也是nodeU
的后继edgeUV
既是nodeU
的入度也是nodeU
的出度edgeUV
既是nodeV
的入度也是nodeV
的出度
一条连接节点本身的边被称为自环(self-loop),也就是说,一条边连接了两个相同的节点。如果这个自环是有向的,那么这条边既是节点的入度边也是节点的出度边,这个节点既是边的起点(source
)也是边的终点(target
)。
如果两条边以相同的顺序连接相同的节点,则称这两条边为平行边(parallel
);如果以相反的顺序连接相同的节点则称这两条边为逆平行边(antiparallel
)。(无向边不能被称为逆平行边)
例如:
//有向图
directedGraph.addEdge(nodeU, nodeV, edgeUV_a);
directedGraph.addEdge(nodeU, nodeV, edgeUV_b);
directedGraph.addEdge(nodeV, nodeU, edgeVU);
//无向图
undirectedGraph.addEdge(nodeU, nodeV, edgeUV_a);
undirectedGraph.addEdge(nodeU, nodeV, edgeUV_b);
undirectedGraph.addEdge(nodeV, nodeU, edgeVU);
在有向图directedGraph
中,边edgeUV_a
和边edgeUV_b
是相互平行边,与边edgeVU
是逆平行边;
在无向图undirectedGraph
中,边edgeUV_a
、edgeUV_b
和edgeVU
是两两相互逆平行边。
功能(Capabilities)
common.graph
模块的核心是提供图相关操作的接口和类。另外,它没有提供类似I/O
或者可视化的功能。如果选用这个模块将会有非常多的限制,具体详细信息可以查看下面FAQ
的相关主题。总体来讲,它提供了如下几种类型的图:
- 有向图
- 无向图
- 节点和(或)边带权图
- 允许(不允许)自环图
- 允许(不允许)平行边图(允许平行边图有时也称为多重图(
multigraphs
) - 节点或边被有序插入、顺序、无序图(graphs whose nodes/edges are insertion-ordered, sorted, or unordered)
Javadoc
中有这样的描述:common.graph
中的各种类型的图都是通过与其相关的Builder
具体实现类型来构建的,不过这些Builder
实现类型不一定支持上面提到的所有图类型,但也可能支持其他类型的图。
库中图的数据结构是通过矩阵
、邻接list
或邻接map
等方式来存储的,选择何种存储方式取决于适用的实现场景。
对于以下这些变形图在common.graph
中没有确切的支持,尽管它们可以通过已有的图类型进行建模:
common.graph
不允许图中同时存在有向边和无向边。Graphs
中提供了很多基本操作(如:图的拷贝和比较操作)。
图的类型
common.graph
模块中有三种通过边来作为区分依据的"top-level
"接口(interface
):Graph
、 ValueGraph
、和