我计划用C ++表示一个相当大,稀疏,无向的图形结构。这将是10,000多个顶点的数量级,每个顶点的度数大约为10。
我已经阅读了一些background来表示图形作为邻接矩阵或列表,但是它们中的较近似乎适合我想要做的事情。在我的场景中:
这是最后一点,使邻接矩阵看起来不合适。据我所知,每个查询都需要2 * N个操作,其中N是图中的节点数。
我认为邻接列表会减少所需的操作,但似乎不合适,因为我在每个边缘包含的参数 - 即因为邻接列表存储每个
是否有更好的方法来存储我的数据,以便这些查询操作更快,我可以使用其参数存储每个边缘?我不想开始实施一些不正确的方法。
答案 0 :(得分:7)
在这里,我没有看到通常的面向对象方法的问题。拥有Edge<V,E>
和Vertex<V,E>
类型,其中V
是顶点存储的内容,E
是边缘存储的内容。每个边都有两个对其各自顶点的引用和两个索引,它们说明在相应顶点的哪个槽中寻找这个边:
template <typename V, typename E>
class Edge {
struct Incidence {
size_t index;
Vertex<V,E>& v;
};
std::array<Incidence,2> vertices;
E content;
};
template <typename V, typename E>
class Vertex {
std::vector<Edge<V,E>*> edges;
};
如果您移除了边e
,则转到Vertex<V,E>::edges
并将back
的位置移至e
的上一个位置。恒定时间删除。用于枚举特定边的所有相邻边的线性时间(在操作结果的大小中)。听起来不错。
答案 1 :(得分:1)
这样的事情似乎有道理吗?这存储边缘邻接:
#include <vector>
#include <map>
typedef int vertex;
struct edge
{
vertex a,b;
// other data
};
bool operator< (const edge &a, const edge &b)
{
unsigned long long ahash = a.a;
ahash << 32;
ahash |= a.b;
unsigned long long bhash = b.a;
bhash << 32;
bhash |= b.b;
return ahash < bhash;
}
// support for your query operation
typedef std::map<edge, std::vector<edge &> > edge_adjacency;
看起来你想要将边缘映射到顶点,然后使用非常标准的东西。