JAVA Graph / DFS实现

时间:2014-09-22 08:50:28

标签: java performance graph depth-first-search

我希望得到一个小小的困境 -

我正在实现一个图形(定向),我想让它更加通用 - 即Graph,其中T是节点(顶点)中的数据。 要向图表添加顶点,请添加(T t)。该图将T包装到一个将T保持在内部的顶点。

接下来我想在图表上运行DFS - 现在这就是我的困境 - 我应该在顶点(作为成员)保留“已访问”标记,还是在运行DFS时启动一些地图(顶点地图 - >状态)?

保持它在顶点不太通用(顶点不应该熟悉DFS算法和实现)。但是创建地图(顶点 - >状态)非常耗费空间。

您怎么看?

非常感谢!

1 个答案:

答案 0 :(得分:3)

如果您需要运行算法,尤其是更复杂的算法,您很快就会发现必须将所有类型的数据与顶点相关联。使用图形项存储数据的通用方法是一个好主意,当然,读取和写入数据的访问时间应该是O(1),理想情况下。简单的实现可能是使用HashMap,它对大多数情况都有O(1)访问时间,但因子相对较高。

对于yFiles Graph Drawing Library,他们添加了一种机制,其中数据实际存储在元素本身,但您可以根据需要分配尽可能多的数据槽。这类似于使用每个元素管理Object[]并将索引作为“map”使用数据数组。如果您的图形没有改变,另一种策略是使用元素本身(只是整数)存储图形中元素的索引,然后使用该索引索引到数组中,对于每个“数据映射”,您基本上具有一个数组元素数量的大小。这两种技术都可以很好地扩展并提供最佳的访问时间,除非您的数据非常稀疏(实际上只需要存储数据的一小部分)。

“元素Object[]”方法:

  • 在您的顶点和边类中,添加一个类型为Object[]的字段,该字段是包私有的。
  • 实施提供MapT getData(Vertex)
  • void setData(Vertex, T界面
  • 该接口的一个实现可以由HashMap<Vertex,T>支持,但我建议的实际上只存储一个整数index,用于索引顶点的Object[]数组。
  • 在图表类中添加一个方法createMap,用于跟踪已使用和自由的索引,并创建上述类的新实例,其getter和setter实现使用Vertex类的包私有字段来实际访问数据

“One Array”方法:

  • 将包私有整数字段添加到Vertex类
  • 使整数字段与图表中顶点的顺序保持同步 - 第一个Vertex具有索引0等。
  • 在替代地图实现中,您最初会分配一个大小为T[]的{​​{1}} 顶点数。
  • 在getter和setter实现中,您获取Vertex的索引并使用它来访问数组中的值。

对于DFS算法,我会选择“一个数组” - 方法,因为你可以使用一个byte [](如果只需“访问”,你甚至可以使用BitSet)来提高空间效率如果您的图表已连接,您可能会填充DFS中所有顶点的数据。这应该比基于HashMap的方法执行得更好,并且不需要装箱和拆箱来将数据存储在Object[]中。