我正在考虑图数据结构的实现,并正在研究“关联列表”表示。这里有一个简短的描述:
Incidence list
所以图中的每个顶点都存储了一个它所关联的边的列表。
考虑到我的图是一个有向图,我对以下几点的描述不是很清楚:
1.图本身是否也存储所有边的列表?
1.顶点只存储向外的边,还是传入和向外的边?
1.如果两者都是,它们是否在单独的列表中?
我非常熟悉其他的图形表示(邻接列表,邻接矩阵,边列表,关联矩阵),所以这不是一个关于一般图形实现的问题,只是这个特殊的问题。
任何指针将不胜感激。
我正在考虑图数据结构的实现,并正在研究“关联列表”表示。这里有一个简短的描述:
Incidence list
所以图中的每个顶点都存储了一个它所关联的边的列表。
考虑到我的图是一个有向图,我对以下几点的描述不是很清楚:
1.图本身是否也存储所有边的列表?
1.顶点只存储向外的边,还是传入和向外的边?
1.如果两者都是,它们是否在单独的列表中?
我非常熟悉其他的图形表示(邻接列表,邻接矩阵,边列表,关联矩阵),所以这不是一个关于一般图形实现的问题,只是这个特殊的问题。
任何指针将不胜感激。
4条答案
按热度按时间ee7vknir1#
我知道我可能提出了一个死人的老问题,但我觉得评论一下是合适的。
你可以创建一个关联列表图结构,也可以调整它的有向图。
考虑一个
LinkedList<Vertex>
对象和一个LinkedList<Edge>
对象。这将允许你覆盖所有的边和顶点,但不包含任何关于所有东西是如何连接的信息。假设我们添加几个
LinkedList<Connection>
对象。实际上,每个Vertex
都有一个。Connection
只是Edge
和Vertex
相遇的地方。因此,Edge
将有两个Connection
对象(对于无向图),一个Vertex
将有一个LinkedList<Connection>
对象,表示与连接到它的每个Edge
的连接。本质上,这是一个关联列表。如果删除了其中的一些
Connection
对象,则可以修改它以表示有向图。更具体地说,您必须选择在何处不包含这些引用。如果您不想从Vertex
中看到Edge
,则可以选择从关联的LinkedList<Connection>
中删除Connection
(对于上面的例子,N2将有一个空的LinkedList<Connection>
)。你可以选择在Edge
上使引用可选(对于上面的例子,E1将有一个指向N2的Connection
和一个空的Connection
,允许从E1遍历到N2,但不会回到N1上。如何实现这一点完全取决于您的选择。一个更直观-边缘是定向的,因此删除边缘上的连接以指定它们的方向似乎是合乎逻辑的。另一个乍看起来可能有点复杂,但可以阻止您在进行广度优先和深度优先搜索时不必要地跳到没有方向的边缘上。以点的形式:
1.在我实现的一个关联列表中,我有。你需要为你的实现?
1.严格地说,你可以通过只存储向外的边来得到。然而,回溯算法可能会受益于能够沿着它们走过的引用进行沿着。当然,你可以围绕这一点实现,使用某种历史记录,所以这可能不是一个需要考虑的问题。
1.如果你两个都做,你可能需要一些方法来区分它是传入还是传出。无论是在顶点上有两个
LinkedList<Connection>
对象,还是在Connection
上有一个boolean pointingToVertex
原语,或者其他什么。也许你的Edge
会被定向,而无向边则由 * 两条 * 指向相反方向的边组成。根据您的结构需要进行考虑。xqk2d5yq2#
我用下面的方法实现了一个关联列表,没有发现无向图的任何问题。我还实现了几个图拓扑算法。
字符串
使用集合Map保证了顶点查找的O(1)和边插入和删除的摊销O(1)复杂度。保持边的关联列表而不是相邻顶点列表只是一种携带边本身的某些特定信息的方式。这对于抽象算法也很有用,例如,当你将权重与边关联时。
编辑:
我已经在维基百科上更新了talks的“发病率列表”主题。
wfypjpf43#
经过进一步的研究和思考,我得出的结论是,没有一个发病率列表图数据结构。我认为维基百科的文章是作者头脑中一些混乱的产物。感谢大家谁读这个问题,并花了任何时间在它上面。
阿尔芒
kiz8lqtg4#
关联列表是邻接列表的另一个名称。
1.您可以将边单独存储在图中,也可以不存储在图中,这是您的选择。通常,如果您使用Java引用链接边列表中的边,您不需要单独存储边。但是您可能更喜欢使用边索引而不是Java引用来集中存储边和链接边。这种方式对于将图序列化到外部存储器更自然,因为边索引将被写为而Java引用需要首先转换为索引。
个字符
1.如你所愿,对于一个典型的图算法来说,存储输出边就足够了。
1.是的