What is an adjacency list and how do you code one?

做~自己de王妃 提交于 2019-12-03 20:43:07
Kerrek SB

A simple example: Suppose you have a vertex type Vertex. They your graph consists of a set of vertices, which you can implement as:

std::unordered_set<Vertex> vertices;

Now for every pair of vertices between which there is an edge in your graph, you need to record that edge. In an adjacency list representation, you would make an edge type which could be a pair of vertices, and your adjacency list could simply be a list (or again a set) of such edges:

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

(You will probably want to supply the last set with an undirected comparator for which (a,b) == (b,a) if you have an undirected graph.)

On the other hand, if you want to make an adjacency matrix representation, you would instead create an array of bools and indicate which vertices have edges between them:

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

(For this you would need a way to enumerate the vertices. In an undirected graph, the adjacency matrix is symmetric; in a directed graph it need not be.)

The list representation is better if there are few edges, while the matrix representation is better if there are a lot of edges.

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

AdjacencyList holds an array of all of the Nodes, and each Node has links to all the other Nodes in the list. Technically the AdjacencyList class isn't required, all that's required is a std::shared_ptr<Node> root;, but having an the AdjacencyList with a vector makes iterating over them, and many other things, much easier.

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

AdjacencyList holds pointers to A, B, C, D, E, and F.
A has pointers to B and C.
B has pointers to A and D and E.
C has pointers to A.
D has pointers to B and E. E has pointers to B and D.
F has pointers to no other nodes.

The AdjacencyList must contain pointers and not Node values, or else when it resizes, all the Neighbors pointers would be invalidated.

So, Boost includes an adjacency_list container as part of boost::graph.

In general, and adjacency list is more than a singly linked list. It describes the direct connections (potentially, of a given direction) of any vertex to other vertices in the graph.

The boost docs provide a few basic examples, with pictures.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!