表示多图的良好数据结构(c++)
Good data structure for representing multigraph (C++)
描述无方向多图(针对速度和内存进行了优化)的最佳数据结构是什么?
边列表是不合适的,因为获取顶点的邻居在我的代码中经常发生。
邻接表不是很好,因为我必须保存访问过的边的信息,当从1到3的边被访问时(假设我遍历1的邻居,找到一条通往3的边,权值为w
),我必须在3的邻居列表中找到相同的边,将其标记为访问过,这很慢。
我考虑过邻接矩阵,当每个细胞都是set<Edge>
时,其中Edge
是一个结构,表示是否访问顶点,边的权重等信息。然而,当访问graph[0][1][i]
时,如果不进行线性搜索,我就不能在graph[1][0]
的边中设置相同的边。
表示多图时有什么好的方法和技巧吗?我不想要像boost::AdjacencyList
这样的第三方库解决方案;我必须自己写。
编辑:很抱歉误解。这是大学的一个练习,我只能用标准库来做。图中有约束条件:0 & lt;N≤300 -顶点数0 & lt;M≤20000—边数1≤w≤500
我的内存限制为32 MB,时间限制为0.5s(我必须使用DFS遍历)。
下面是提供高效本地操作的稍微复杂的表示
struct Link;
struct Node
{
Link *firstIn, *lastIn, *firstOut, *lastOut;
... node data ...
};
struct Link
{
Node *from, *to;
Link *prevInFrom, *nextInFrom, *prevInTo, *nextInTo;
... link data ...
};
基本上每个Node
都有两个双链表,一个用于传入链接,一个用于传出链接。每个Link
都知道开始和结束的Node
,并且对于包含它的两个列表("from"节点中的传出列表和"to"节点中的传入列表)也有prev和next指针。
使用此方法,您将获得O(1)
节点和链接的创建和销毁,O(inbound_deg(node))
用于查找到达节点的链接,O(outbound_deg(node))
用于查找离开节点的链接。该结构还支持同一对节点之间的多个连接以及多个环路。
每个节点和每个链接所需的空间是固定的,但是开销可以根据应用程序(每个节点4个指针,每个链接6个指针)确定是否合适。使用简单链表代替双链表,开销变为每个节点2个指针和每个链接4个指针,但链接删除变为O(outbound_deg(from) + inbound_deg(to))
并且不再是常量。
还请注意,所示的结构不是缓存友好的,在现代台式计算机中可能是一种更"暴力"的方法,例如,指针的向量代替双链表可以提供更好的速度,这取决于列表的大小和你改变图结构的频率。
甚至可以拆分链接对象以嵌入前向链接数据,例如在"from"节点中,在"to"节点中保留反向指针。
struct Node
{
struct OutgoingLink
{
Node *to;
int incoming_index;
... link data ...
};
struct IncomingLink
{
Node *from;
int outgoing_index;
};
std::vector<OutgoingLink> outgoing_links;
std::vector<IncomingLink> incoming_links;
... node data ...
};
如果你大部分时间都在正向遍历链接,如果链接没有添加到现有的节点上,那么最好是为一个节点和传出的链接数据使用一个内存块,但不幸的是,c++不容易支持这一点。
在C语言中应该是
typedef struct TOutgoingLink
{
struct TNode *to;
int incoming_index;
... link data ...
} OutgoingLink;
typedef struct TIncomingLink
{
struct TNode *from;
int outgoing_index;
} IncomingLink;
typedef struct TNode
{
... node data ...
int num_incoming_links;
int num_outgoing_links;
IncomingLink *incoming_links; // separate array
OutgoingLink outgoing_links[1]; // embedded array starting here
} Node;
使用malloc(sizeof(Node) + (num_outgoing_links-1)*sizeof(OutgoingLink))
为节点分配空间
使用这种方法,节点及其传出链接的所有数据将位于相邻的内存位置。
- 链表,反向函数,数据结构
- 如何使用set实现无序数据结构?
- 我们可以将数据永久保存为数据结构吗?
- C++中的可变长度数组/数据结构
- 用于存储由空格分隔的字符串的 C++/C 数据结构
- 通过 NIF 从C++返回自定义数据结构
- 编译器上的策略数据结构不起作用
- 尝试构建"lock-free"数据结构C++
- 设计将引用元素移动到开头的数据结构.C++
- 在学习数据结构之前对STL有一个了解是好的吗?
- 如何解析表示树状数据结构的字符串
- 我对数据结构、双向链表有一些问题
- googletest:测试太大的数据结构
- C++中deque数据结构的大O是什么?
- 我可以使用哪种数据结构来处理这种方式
- 将文本文件解析为树状数据结构
- C++ 中具有 O(1) 搜索时间复杂度的数据结构
- 哪些存储了不完整类型的 STL 数据结构可以用作类成员?
- C++,您能否设计一种数据结构,将指针保存在连续内存中并且不会使它们失效?
- 带参数的数据结构的全局声明