我刚刚开始使用图论。我不知道如何使用链表对邻接表进行编码。例如,如果我有这个图(无向):
A--------B
| /|\
| / | \
| / | \
| / | \
| / | \
| / | \
| / | \
C E-------D
我该如何编码?我知道如何使用邻接矩阵来做到这一点,但是如何使用邻接列表和链表(c++)对其进行编码?
我刚刚开始使用图论。我不知道如何使用链表对邻接表进行编码。例如,如果我有这个图(无向):
A--------B
| /|\
| / | \
| / | \
| / | \
| / | \
| / | \
| / | \
C E-------D
我该如何编码?我知道如何使用邻接矩阵来做到这一点,但是如何使用邻接列表和链表(c++)对其进行编码?
邻接列表只是列表的向量/数组。图中的每个元素都是数组中的一个元素,并且任何边都被添加到它的邻接列表中。因此它看起来像:
A -> {B, C}
B -> {A、C、D、E}
C -> {A, B}
D -> {B, E}
E -> {B, D}
所以我们从类似的东西开始std::vector<std::list<vertex>>
。但是,我们可以做得更好,因为顶点是唯一的,因此我们可以利用map
. 此外,一个顶点只能在一个边列表中出现一次,因此我们将其修改为std::map<vertex, std::set<vertex>>
。
因此,首先,例如:
struct vertex
{
//
};
class undirected_graph
{
private:
std::map<vertex, std::set<vertex>> graph_container;
public:
void add_vertex(const vertex& v) { //add a vertex to the map }
void add_edge(const vertex& v, const vertex& u) { //look up vertex in map and add to the vertex adjacency list }
//Other methods
//...
};
邻接表只是表示图边缘的一组对象。
struct edge {
node *nodes[2];
edge( node *a, node *b ) {
if ( a < b ) { // define canonical order of edges for undirected graph
nodes[0] = a;
nodes[1] = b;
} else {
nodes[0] = b;
nodes[1] = a;
}
}
};
链表听起来不是特别实用。通常你会定义边的顺序并将它们放在 astd::set
或std::map
中。
bool operator< ( edge const &lhs, edge const &rhs ) {
if ( lhs.nodes[0] < rhs.nodes[0] ) return true;
if ( rhs.nodes[0] < lhs.nodes[0] ) return false;
return lhs.nodes[1] < rhs.nodes[1];
}
typedef std::set< edge > graph;
有很多方法可以做到这一点,如果不知道您打算对图表做什么,就很难提出更多建议。
您可以从以下repo (CXXGraph)的源代码中获得灵感。
这个 repo 包含一个只有头文件的库和一个邻接矩阵的实现。