什么是邻接列表,你如何编码?

时间:2011-10-19 01:35:51

标签: c++ graph adjacency-list

这是邻接列表的SO post。但是我发现单链表没有区别?这里还有一个wikipedia article,它表示列表中的所有边(图中的离散数学类型)非常宽,如果我有一个图,它不是路径图。如何编写邻接列表?

3 个答案:

答案 0 :(得分:5)

一个简单的例子:假设你有一个顶点类型Vertex。它们的图形由一组顶点组成,您可以将它们实现为:

std::unordered_set<Vertex> vertices;

现在,对于图形中有边缘的每对顶点,您需要记录该边缘。在邻接列表表示中,您将创建一个可以是一对顶点的边类型,并且您的邻接列表可以只是这样的边的列表(或者再一组):

typedef std::pair<Vertex, Vertex> Edge;
std::list<Edge> edges_as_list;
std::unordered_set<Edge> edges_as_set;

(如果您有无向图,您可能希望为最后一组提供带有(a,b) == (b,a)的无向比较器。)

另一方面,如果你想制作一个邻接矩阵表示,你可以创建一个bool数组,并指出哪些顶点之间有边缘:

bool edges_as_matrix[vertices.size()][vertices.size()]; // `vector` is better
// edges_as_matrix[i][j] = true if there's an edge

(为此你需要一种枚举顶点的方法。在无向图中,邻接矩阵是对称的;在有向图中它不一定是。)

如果边缘很少,列表表示会更好,而如果边缘很多,矩阵表示会更好。

答案 1 :(得分:3)

struct Node {
    std::vector<std::shared_ptr<Node>> Neighbors;
};
struct AdjacencyList{
    std::vector<std::shared_ptr<Node>> Nodes;
};

AdjacencyList包含所有Node的数组,每个Node都包含指向列表中所有其他Node的链接。从技术上讲,AdjacencyList类不是必需的,所需要的只是std::shared_ptr<Node> root;,但AdjacencyList的{​​{1}}会使vector迭代,以及许多其他内容,更容易。

A----B  F
|    |\
|    | \
C    D--E
     

AdjacencyList指向ABCDEF
  A指向BC   B指向AD以及E   C指向A
  D指向BE。   E指向BD   F指向其他节点。

AdjacencyList必须包含指针而不是Node值,否则在调整大小时,所有Neighbors指针都将失效。

答案 2 :(得分:2)

因此,Boost包含一个adjacency_list容器作为boost :: graph的一部分。

一般而言,邻接列表不仅仅是单链表。它描述了任何顶点到图中其他顶点的直接连接(可能是给定方向)。

boost docs提供了一些基本示例和图片。