我正在设计应基于图形的应用程序。 我不确定哪一种是在内存中表示图形邻接表的最佳方法。客户的要求非常模糊,因此我必须做一些假设。图的节点是一些ID,但是我不确定ID是否是顺序的。当涉及一般规格时,图论怎么说? 如果它们是顺序的,则节点数(N)也应限制最大ID,并且基本上可以确保ID覆盖区间 1,2…N 。请参阅下面的选项A。 如果它们不是顺序的,则ID可以从1跳到例如。 11,可能会跳过规范中的某些自然数。请参阅下面的选项B。 在ID旁边,还有一个c ++数据结构,我在其中存储多个信息(有效负载,连接的边等)。 我的算法还有两个选择:
A。将图形表示为向量,向量的索引将表示nodeID。
B。将图形表示为map,其中Node ID是键,而Data是存储值。
地图可以让我拥有随机ID,比如说输入数据是随机提供的。
文献(例如DFS,BFS或其他图形文章)主要考虑选项A,其中节点ID完全覆盖间隔 [1..N] 。我也会选择这个选项,因为它代表了一个公认的符号。 然后,将其添加到我的应用程序的“文档/前提条件”部分。
正确掩盖客户的歧义规格的最佳选择是什么?
答案 0 :(得分:0)
您可以选择将图形表示为两个列出的选项的组合:具有包含两个成员的Node
结构-整数label
和您需要的另一个结构。
该图将存储一个std::vector<Node*> nodes;
。但是,鉴于节点的标签与上面的向量中的位置不匹配的限制,您需要将标签和向量索引之间的对应关系存储在std::map<int, int> corresp;
鉴于此结构,如果您需要访问标签值为11的Node *,则可以执行Node* node = nodes[corresp[label]];
此外,标签可以是任何其他类型,例如std::string
。唯一需要做的修改就是将映射的键类型更改为std::string
。
答案 1 :(得分:0)
情况1:顺序ID。然后,您可以按照索引对应于ID的方式将节点存储在数组中。
情况2:稀疏ID。
通常,图节点的表示允许它们具有有效负载(属性),例如ID。如果不需要按ID访问节点,则使用数组即可。
如果确实需要通过ID访问节点,请使用字典(映射)建立对应关系。您也可以将节点直接存储在字典中,但是节点枚举或排序会比较困难。
答案 2 :(得分:0)
我通常建议使用(可能是智能的)指针标识对象(如果它们是对象),因为C / C ++提供了这种机制来标识对象。
从根本上讲,您的图由许多节点和边组成,因此通常会出现以下情况:
public class OtherFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//just change the fragment_dashboard
//with the fragment you want to inflate
//like if the class is HomeFragment it should have R.layout.home_fragment
//if it is DashboardFragment it should have R.layout.fragment_dashboard
return inflater.inflate(R.layout.fragment_other, null);
}
}
然后,在您的class Node {
int id;
Data data;
std::vector<Node *> edges;
}
类中,您将需要每种用于访问节点的 other 方式的映射。您可能需要能够按ID查找节点,因此图类将为此需要某种索引-密集ID为Graph
或稀疏ID为vector<Node *> nodesById
。选择哪个不应该是一个具有很多后果的重要决定。添加方法map<int,Node*> nodesById
,然后可以随时更改表示形式。始终记住,在软件开发中,当一个决定没有明显的答案,或者当未来可能会改变最佳答案时,轻松改变主意比做出正确决定要好得多。选择。
随着人们向您的图形添加需求,您可能需要以不同的方式访问节点,并且可能必须添加更多种类的索引来支持那些特定的用例。
您需要对图形执行的两个工作是构造和破坏。构造可能需要Node *getNodeById(int id)
索引。销毁肯定需要某种方法来枚举所有节点,并且您为nodesById
选择的任何表示形式也都足以满足要求。
答案 3 :(得分:0)
您可以使用向量图。像这样:
Map<int,vector<Node *>>;
此映射中的键将是您的节点ID。对应的向量具有第一个条目作为该特定ID的对应节点,然后具有该ID节点的所有边。
假设您的图有一个ID为2的节点,并且该节点的边为ID为3,4和6的节点。
因此,与地图中的键2对应的条目将是一个向量,其第一个条目作为ID为2的节点,然后其下一个条目作为ID 3的节点,然后为4,最后是节点6。
您的Node的每个矢量条目看起来都类似于此:
struct Node {
int id,
InfoData obj;
}