初步说明
您可以考虑使用向量的向量来代替动态内存分配:
vector<vector<int>> AdjList(V);
无论如何,您将在邻接表中拥有V个不同的
vector<int>
。每个向量都需要一些空间开销来管理其项目的大小和位置。不幸的是,通过在不同的向量/数组中保留权重,您会使这种开销加倍(以及与添加新链接相关的隐藏内存管理)。那么为什么不重新组合邻接表和权重呢?
struct Link {
int target; // node number that was in adj list. Hope none is negative!!
int weight;
};
vector<vector<Link>> AdjList(V);
这个结构是稀疏的吗?
如果大多数节点都有某种链接,那就很好。
如果相反,许多节点没有出站链接(或者您有大量未使用的节点ID范围),则可以考虑:
map<int, vector<Link>> AdjList;
map 是一种关联数组。只有具有出链的节点才会有向量。顺便说一句,您可以使用任何编号方案,甚至负数。
您甚至可以更进一步,使用双重映射。第一个映射给出了出链的节点。第二个映射将目标节点映射到其权重:
map<int, map<int, int>> Oulala;
但这可能会占用更多的内存。
大容量?
使用默认分配器,
map
和
vector
动态管理内存。但是如果您有很多预定大小的小对象,则可以考虑使用自己的
分配器。这可以显着优化内存管理开销。
此外,如果您使用向量,在加载新节点的邻接列表时,立即为向量保留大小(如果您知道它)可能是有效的。这可以避免向量增长的几次连续重新分配。 对于数百万个节点,这可能非常昂贵。
图书馆?
在SO上搜索第三方库超出了范围。但是,如果以上提示不足够,则可以考虑使用现有的图形库,例如:
还有其他一些图形库可用,但许多库似乎已不再维护或者没有设计用于大容量。
V
向量的数组。老实说,看一下一些 C++ 图库,并确保你知道 C++ 语言本身的基础知识。 - Ulrich EckhardtV
,因为向量的数量也将是V
。但程序需要找出每个节点有多少相邻节点。因此,我创建了V
个向量,然后在程序内部开始向每个向量添加相邻节点。 - viz12