图邻接表的不同实现的利弊

时间:2020-07-01 19:39:57

标签: python graph adjacency-list

我已经看到了图的邻接表的多种表示形式,但我不知道要使用哪个。

  1. 我正在考虑以下Node对象和Graph对象的表示形式(如下所示)
class Node(object):
    def __init__(self, val):
        self.val = val
        self.connections_distance = {}
        # key = node: val = distance

        def add(self, neighborNode, distance):
            if neighborNode not in self.connections_distance:
            self.connections_distance[neighborNode] = distance

class Graph(object):
    def __init__(self):
        self.nodes = {}
        # key = node.val : val = node object

        # multiple methods
  1. 第二种方式是将节点标记为0-n-1(n是节点数)。每个节点将其邻接关系存储为一组链接列表(其中索引是节点值,而链接列表存储其所有邻居)

例如图:

0连接到1和2
1连接到0和2
2连接到0和1

或者如果[a,b,c]是并且包含a,b和c的数组,并且[x-> y-> z]是包含x,y和z的链表:

表示形式:[[1->2], [0->2], [0->1]]

问题:每种表示形式的优缺点是什么,使用更广泛的是什么?

1 个答案:

答案 0 :(得分:1)

注意:一种表示包含距离而另一种不包含距离是有点奇怪的。他们俩都容易包括距离,或者两者都忽略,所以很容易,所以我将省略细节(您可能对set()而不是{}感兴趣)。

这两种表示形式似乎都是邻接表的变体(在https://stackoverflow.com/a/62684297/3798897中有进一步说明)。从概念上讲,这两种表示形式之间没有太大区别-您有一个节点集合,每个节点都有一个对邻居集合的引用。您的问题实际上是两个独立的问题:

(1)您应该使用字典还是数组来保存节点集合?

  • 它们几乎相等;字典只不过是幕后的数组而已。如果您没有足够的理由这样做,则依靠内置字典而不是使用自己的哈希函数和密集数组重新实现字典将是正确的选择。
  • 字典将占用更多空间
  • 从字典中删除字典会更快(如果实际上是数组而不是python的列表,则插入也会如此)
  • 如果您有一种快速的方法来为每个节点生成数字1-n,那么它可能比字典在后台使用的哈希函数更好,因此您可能要使用数组。

(2)是否应该使用集合或链接列表来保存相邻节点的集合?

  • 几乎可以肯定您想要一套。至少在渐近性上好于您要与邻居集合进行任何处理的列表,它对缓存更友好,对象开销更少,依此类推。

与往常一样,您的特定问题可以左右选择。例如,我提到数组的插入/删除性能要比字典差,但是如果您几乎不执行插入/删除操作,那将无关紧要,稍微减少的内存将开始具有吸引力。