【问题标题】:Implementation of an adjacency list graph representation邻接表图表示的实现
【发布时间】:2013-01-03 04:35:54
【问题描述】:

我刚刚开始学习图论。我不知道如何使用链表对邻接表进行编码。例如,如果我有这个图(无向):

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

如何编码?我知道如何使用邻接矩阵来做到这一点,但是如何使用邻接列表和链表(c++)对其进行编码?

【问题讨论】:

    标签: c++ data-structures graph-theory


    【解决方案1】:

    邻接列表只是列表的向量/数组。图中的每个元素都是数组中的一个元素,并且任何边都被添加到它的邻接列表中。因此它看起来像:

    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
        //...
     };
    

    【讨论】:

    • 来自Wikipedia:“在图论中,邻接表是将图中的所有边或弧表示为一个列表。”您实现的可能是对它的优化,但基本概念有点模糊。
    • @PushkarMishra 当然。如果您是第一次尝试实现此功能,请使用最简单的方法。
    • 向量是一种有效的选择吗?
    • 好吧,邻接列表与邻接矩阵的重点在于,对于没有太多边的图,它们的内存效率更高。 map/set 实现可能会更快,但对于任何不太大的图表,差异可能很小。
    • 使用 std::map 作为邻接列表将导致 bfs/dfs 遍历的 O(|V|*log(|V|)+|E|) 复杂度,其中 |V|,|E|分别是顶点和边的大小。因此对于稀疏矩阵,会导致更高的时间复杂度。
    【解决方案2】:

    邻接表只是表示图边缘的一组对象。

    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;
            }
        }
    };
    

    链表听起来不是特别实用;通常你会定义边的顺序并将它们放在std::setstd::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;
    

    有很多方法可以做到这一点,如果不知道您打算对图表做什么,就很难提出更多建议。

    【讨论】:

      【解决方案3】:

      您可以从以下repo ( CXXGraph )的源代码中获得灵感。

      这个 repo 包含一个只有头文件的库和一个邻接矩阵的实现。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-16
        • 1970-01-01
        • 2018-07-14
        • 1970-01-01
        相关资源
        最近更新 更多