这是邻接列表的SO post。但是我发现单链表没有区别?这里还有一个wikipedia article,它表示列表中的所有边(图中的离散数学类型)非常宽,如果我有一个图,它不是路径图。如何编写邻接列表?
答案 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
指向A
,B
,C
,D
,E
和F
。
A
指向B
和C
B
指向A
和D
以及E
C
指向A
。
D
指向B
和E
。E
指向B
和D
F
指向其他节点。
AdjacencyList必须包含指针而不是Node
值,否则在调整大小时,所有Neighbors
指针都将失效。
答案 2 :(得分:2)
因此,Boost包含一个adjacency_list容器作为boost :: graph的一部分。
一般而言,邻接列表不仅仅是单链表。它描述了任何顶点到图中其他顶点的直接连接(可能是给定方向)。
boost docs提供了一些基本示例和图片。