web-dev-qa-db-ja.com

隣接リストグラフ表現の実装

グラフ理論を始めたばかりです。リンクリストを使用して隣接リストをコーディングする方法がわかりません。たとえば、このグラフ(無向)がある場合:

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

どうすればコーディングできますか?隣接行列を使用してそれを行う方法を知っていますが、隣接リストとリンクリスト(c ++)を使用してコーディングする方法はありますか?

9
Somebody

隣接リストは、リストの単なるベクトル/配列です。グラフの各要素は配列の要素であり、エッジはその隣接リストに追加されます。したがって、次のようになります。

A-> {B、C}

B-> {A、C、D、E}

C-> {A、B}

D-> {B、E}

E-> {B、D}

したがって、std::vector<std::list<vertex>>のようなものから始めます。ただし、頂点は一意であるため、これよりもうまくいくことができます。したがって、mapを利用できます。さらに、頂点はエッジリストに1回しか表示できないため、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
    //...
 };
14
Yuushi

隣接リストは、グラフのエッジを表すオブジェクトのセットにすぎません。

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

これを行うには多くの方法がありますが、グラフで何をしようとしているのかを知らずに、これ以上何かを提案することは困難です。

3
Potatoswatter