グラフ理論を始めたばかりです。リンクリストを使用して隣接リストをコーディングする方法がわかりません。たとえば、このグラフ(無向)がある場合:
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
を利用できます。さらに、頂点はエッジリストに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
//...
};
隣接リストは、グラフのエッジを表すオブジェクトのセットにすぎません。
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;
これを行うには多くの方法がありますが、グラフで何をしようとしているのかを知らずに、これ以上何かを提案することは困難です。