使用图表的地图

时间:2012-08-30 01:53:05

标签: java data-structures graph map hashmap

您好我要为课程实现图形数据结构(图表不是要求的一部分,我选择用它来解决问题)我首先想到的是使用一个邻接列表,因为它需要更少的内存,我不希望在我的图中有那么多边缘。

但后来发生在我身上。我可以使用Map实现邻接列表Graph数据结构(HashMap是特定的)。而不是顶点列表,我将有一个顶点贴图,然后将一个边的短边列表保存到顶点。

这似乎是我的方式。但是我想知道是否有人可以看到像我这样的学生在使用HashMap时可能错过的任何缺点? (不幸的是,当我们过去HashMap时,我记得很累...所以我对它们的了解比我所知道的所有其他数据结构要少。)所以我想确定。

顺便说一句,我正在使用Java。

2 个答案:

答案 0 :(得分:9)

表示图表的两种主要方式是:

  • 与邻接列表(如您所述)
  • 与邻接矩阵

由于你没有太多的边缘(即代表你的图形的邻接矩阵将是稀疏),我认为你决定使用列表而不是矩阵是一个很好的,因为,你说过,它确实会占用更少的空间,因为没有空间浪费来代表缺席的边缘。此外,Map方法似乎是合乎逻辑的,因为您可以将图表的每个Node映射到它所连接的Node列表。另一种方法是让每个Node对象作为数据字段包含它所连接的节点列表。我认为这些方法中的任何一种都可以运作良好我在下面总结了一下。

第一种方法(维护地图):

Map<Node, Node[]> graph = new HashMap<Node, Node[]>();

第二种方法(内置于Node类的数据):

public class Node {
    private Node[] adjacentNodes;
    public Node(Node[] nodes) { adjacentNodes = nodes; }
    public Node[] adjacentNodes() { return adjacentNodes; }
}

答案 1 :(得分:4)

图表传统上通过邻接列表或邻接矩阵表示(还有其他方法针对某些图形格式进行了优化,例如节点ID是否按顺序标记和/或您知道前面的节点数/边数时间,但我不会进入那个。)

在邻接列表和邻接矩阵之间进行选择取决于您的需求。显然,邻接矩阵将占用比邻接列表更多的空间(矩阵总是占用(节点数)^ 2而列表将占用(节点数+边数),但如果你的图形是“小”那么它并没有真正有所作为。

另一个问题是你有多少边(你的图是稀疏的还是密集的)?您可以通过获取您拥有的边数并将其除以:

来找到图形的密度

n(n-1)/ 2

其中“n”是图的节点数。上面的等式找到“n”节点UNDIRECTED图中可能的边缘总数。如果图表是定向的,则删除“/ 2”。

要考虑的是有效边缘成员资格是否重要。邻接列表可以轻松检测边缘成员资格(O(1)),因为它只是一个数组查找 - 如果“列表”存储为HashSet以外的其他内容,则邻接列表将会慢得多,因为它会更慢必须浏览整个边缘列表。或者也许你保持边缘列表的排序,你可以只进行二分搜索,但边缘插入需要更长的时间。也许您的图表非常稀疏,并且邻接矩阵使用了太多内存,因此您必须使用邻接列表。很多事情要考虑。

可能与您的项目有关的问题有很多,我只列出一些。

通常,假设您的图形不是非常复杂或“大”(在数百万个节点的意义上),HashMap,其中键是节点ID,值是{{1}或者其他一些节点ID集合指示关键节点的邻居是好的,我已经在8GB机器上为400,000多个节点图做了这个。基于Set的实现可能最容易实现。