将边缘数据存储在邻接列表中?

时间:2017-05-02 02:33:59

标签: java algorithm data-structures graph

我正在尝试创建一个由Hashtable支持的简单有向图数据结构,如下所示:

private Hashtable<V, List<Edge<V, K>>> adjacencyTable;

其中V是顶点类型,K是存储在边缘的数据。 Edge类只存储它所在的两个顶点的引用以及类型K的某个对象。所以......

1 | (1, 2, data_1), (1, 3, data_2)
2 | (2, 3, data_3)
3 | (3, 1, data_4)

所以为了做一些简单的事情,比如removeVertex(3),我必须遍历每个顶点的所有边,检查它们的to属性是否等于我想要删除的顶点,然后删除它们。有没有更好的方法来实现这样的东西?

1 个答案:

答案 0 :(得分:2)

是的,你是对的,这是一个尴尬的选择。请改为使用

Map<V, Map<V, K>> adjacencies = new Hashmap<>();

p相邻的节点为adjacencies.get(p).keyset(),边p->q的数据为adjacencies.get(p).get(q)

删除顶点r一定是一项棘手的操作,因为你需要删除r的入边和边出边。但是,您可以通过维护并行的“反向邻接”列表来快速完成。

Map<V, Set<V>> reverseAdjacencies = new Hashmap<>();

每次使用以下内容添加邻接p->q

Map<V, K> edgesFromP = adjacencies.get();
if (edgesFromP == null) {
  edgesFromP = new HashMap<>();
  adjacencies.put(p, edgesFromP);
}
edgesFromP.put(q, nodeData);

反向地图也需要更新,例如

Set<V> edgesToQ = reverseAdjacencies.get(q);
if (edgesToQ == null) {
  edgesToQ = new HashSet<>();
  reverseAdjacencies.put(q, edgesToQ);
}
edgesToQ.add(p);

现在删除节点r

// Remove the in-edges to r.
for (V p : reverseAdjacencies.remove(r)) {
  adjacencies.get(p).remove(r);
}
// Remove r and all its out-edges
adjacencies.remove(r);

我遗漏了空检查等细节。