Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当接收到不明确的规范时,表示图形邻接列表的数据结构_C++_Algorithm_Data Structures_Graph - Fatal编程技术网

C++ 当接收到不明确的规范时,表示图形邻接列表的数据结构

C++ 当接收到不明确的规范时,表示图形邻接列表的数据结构,c++,algorithm,data-structures,graph,C++,Algorithm,Data Structures,Graph,我正在设计一个应用程序,应该是基于图形。 我不确定哪一种是表示内存中图形邻接列表的最佳方式。客户的要求很模糊,所以我必须做一些假设。图中的节点是一些ID,但我不确定这些ID是否是连续的。当涉及到一般规范时,图论说了什么? 如果它们是连续的,节点数(N)也应该限制最大ID,并且基本上可以确保ID将覆盖间隔1,2…N。见下文选项A。 如果它们不是顺序的,则ID可能从1跳到例如11,并且可能跳过规范中的一些自然数。见下文备选案文B。 除了ID之外,还有一个C++数据结构,我存储多个信息(有效载荷、连接

我正在设计一个应用程序,应该是基于图形。 我不确定哪一种是表示内存中图形邻接列表的最佳方式。客户的要求很模糊,所以我必须做一些假设。图中的节点是一些ID,但我不确定这些ID是否是连续的。当涉及到一般规范时,图论说了什么? 如果它们是连续的,节点数(N)也应该限制最大ID,并且基本上可以确保ID将覆盖间隔1,2…N。见下文选项A。 如果它们不是顺序的,则ID可能从1跳到例如11,并且可能跳过规范中的一些自然数。见下文备选案文B。 除了ID之外,还有一个C++数据结构,我存储多个信息(有效载荷、连接边等)。 我的算法还有两个选项:

A.将图形表示为向量,向量的索引将表示节点ID

B.将图形表示为一个映射,其中节点ID是键,数据是存储值

Map允许我拥有随机ID,比如说输入数据是随机给出的

文献(例如DFS、BFS或其他图表文章)主要考虑选项A,其中节点ID完全覆盖一个间隔[1..N]。我也会选择这个选项,因为它代表了一种普遍同意的符号。 然后,将其添加到我的应用程序的文档/前提条件部分


正确覆盖客户含糊不清的规格的最佳选项是什么?

您可以选择将图形表示为列出的两个选项的组合:具有包含两个成员的
节点
结构-一个整数
标签
和另一个所需的结构

图形将存储
std::vector节点。但是,考虑到节点的标签与其在上述向量中的位置不匹配的限制,您需要将标签和向量索引之间的对应关系存储在
std::map corresp

给定此结构,如果需要访问标签值为11的节点*,则可以执行
Node*Node=nodes[corresp[label]]


此外,标签可以是任何其他类型,例如
std::string
。唯一需要做的修改是将映射的键类型更改为
std::string

情况1:顺序ID。然后,您可以将节点存储在一个数组中,使索引对应于ID

案例2:稀疏ID

通常,图中节点的表示形式允许它们具有有效负载(属性),例如ID。如果不需要通过ID访问节点,则使用数组即可


如果确实需要通过ID访问节点,请使用字典(映射)建立对应关系。您也可以将节点直接存储在字典中,但节点枚举或排序将更加困难。

如果它们是对象,我通常建议使用(可能是智能)指针来标识,因为这是C/C++提供的标识对象的机制

基本上,图形由许多节点和边组成,因此通常会有如下内容:

class Node {
    int id;
    Data data;
    std::vector<Node *> edges;
}
类节点{
int-id;
数据;
向量边;
}
然后,在
Graph
类中,对于访问节点所需的每种其他方式,都需要某种类型的映射。您可能需要能够按id查找节点,因此graph类需要某种索引——对于密集id,使用
向量nodesById
;对于稀疏id,使用
映射nodesById
。选择哪一个不应该是一个有很多后果的重要决定。添加一个方法
Node*getNodeById(int-id)
,然后您可以随时更改表示形式。请始终记住,在软件开发中,当一个决策没有明显的答案,或者最好的答案可能在未来发生变化时,那么轻松改变想法比做出正确的选择要好得多

随着人们向图形中添加需求,您可能需要以不同的方式访问节点,并且可能需要添加更多种类的索引来支持这些特定用例


使用图形需要做的两项工作是构造和销毁。构造可能需要
nodesById
索引。销毁肯定需要某种方法来枚举所有节点,并且无论您为
nodesById
选择哪种表示形式,都可以满足这一要求

你可以使用矢量图。大概是这样的:

Map<int,vector<Node *>>;

首先,您必须询问客户ID是否连续。
struct Node {
 int id,
 InfoData obj;
}