比较对象图表示与邻接列表和矩阵表示

时间:2011-05-04 15:53:05

标签: algorithm graph graph-algorithm

我目前正在关注Steve Yegge关于准备技术编程面试的建议:http://steve-yegge.blogspot.com/2008/03/get-that-job-at-google.html

在他关于图表的部分中,他说:

  

有三种基本方法   表示内存中的图形(对象   和指针,矩阵和邻接   列表),你应该熟悉   你自己与每个表示和   它的优点和缺点。

矩阵和邻接列表表示的优缺点在CLRS中描述,但我无法找到将这些与对象表示进行比较的资源。

只要想一想,我就可以自己推断一些,但我想确保我没有错过一些重要的东西。如果有人能够全面地描述这一点,或者指向我这样做的资源,我将非常感激。

3 个答案:

答案 0 :(得分:89)

对象和指针

这些只是像Hammar在其他答案中所说的基本数据结构,在Java中,您可以使用边和顶点等类来表示它。例如,边缘连接两个顶点,并且可以是定向的或不定向的,并且它可以包含权重。顶点可以有ID,名称等。大多数它们都有其他属性。因此,您可以使用它们构建图形,如

Vertex a = new Vertex(1);
Vertex b = new Vertex(2);
Edge edge = new Edge(a,b, 30); // init an edge between ab and be with weight 30  

这种方法通常用于面向对象的实现,因为它对于面向对象的用户来说更具可读性和便利性;)。

<强>矩阵

矩阵只是一个简单的二维数组。假设您有顶点ID,可以表示为这样的int数组:

int[][] adjacencyMatrix = new int[SIZE][SIZE]; // SIZE is the number of vertices in our graph
adjacencyMatrix[0][1] = 30; // sets the weight of a vertex 0 that is adjacent to vertex 1

这通常用于需要索引访问的密集图。您可以使用此表示非/定向和加权结构。

邻接列表

这只是一个简单的数据结构组合,我通常使用HashMap<Vertex, List<Vertex>>来实现。类似的使用可以是番石榴中的HashMultimap

这种方法很酷,因为你有O(1)(摊销的)顶点查找,它返回一个我要求的这个特定顶点的所有相邻顶点的列表。

ArrayList<Vertex> list = new ArrayList<>();
list.add(new Vertex(2));
list.add(new Vertex(3));
map.put(new Vertex(1), list); // vertex 1 is adjacent to 2 and 3

这用于表示稀疏图表,如果您在Google上申请,您应该知道该网页是稀疏的。您可以使用BigTable以更具伸缩性的方式处理它们。

哦和BTW,here是这篇文章的精彩摘要,带有精美的图片;)

答案 1 :(得分:7)

对象和指针与邻接列表大致相同,至少是为了比较使用这些表示的算法。

比较

struct Node {
    Node *neighbours[];
};

struct Node {
    Node *left;
    Node *right;
};

如果比使用命名指针更容易使用,则可以在后一种情况下轻松构建邻居列表。

答案 2 :(得分:4)

对象表示(incidence list)的优点是两个相邻的顶点共享边的相同实例。这使得使用无向边数据(长度,成本,流量或甚至方向)进行操作变得容易。但是它为指针使用了额外的内存。