所以我开始了关于有向图和拓扑排序的项目。我正在寻找以下方式解析课程输入文件的最有效方法:
COURSE_1 COURSE_2
其中COURSE_1是COURSE_2的先决条件
NONE COURSE_3
其中COURSE_3没有先决条件。
显然,所有顶点标签都是字符串。我创建了一个带有数据成员的Graph
类来存储顶点,边和顶点标签。稍后,我将添加拓扑排序方法,并找到从一个顶点到另一个顶点的最短路径。鉴于这些未来计划,我的问题是,使用邻接列表会更好吗?还是矩阵?从输入文件填充图表的最有效方法是什么?我最初的想法是使用邻接列表。由于图表的大小在编译时并不知道我的想法
std::vector<std::list<std::string>> adjacencyList;
另外,我想创建一个帮助函数来解析输入文件。
的内容void populateGraph(std::string filename, Graph* graph)
我在这里完全走错了方向吗?
答案 0 :(得分:1)
你在很多方面走在正确的轨道上。
如果您可以假设您将遇到的所有输入都只是NONE
和COURSE_X
,并且您可以假设所有Xes从1(或0)开始形成连续的整数间隔,并且跨度为顶点的数量,那么你可以在内部将顶点视为数字。如果不是这种情况,您可以为每个顶点标签指定一个数字(例如,使用std :: unordered_map),并保留此抽象结构。
现在,如果您选择坚持使用此模型,则使用起来非常方便,因为您的整个图表可以表示为std::vector<std::list<int>>
。如果要存储有关边缘的更多信息(如标签,权重等),可以用int
替换 VerticalLayout labelLayout= new VerticalLayout();
labelLayout.setWidth("100%");
labelLayout.addComponent(usernameLabel);
labelLayout.addComponent(postLabel);
labelLayout.addComponent(ratioLabel);
labelLayout.addComponent(lowestRatedPost);
labelLayout.addComponent(highestRatedPost);
detailsLayer.addComponent(labelLayout);
wrappercontent.addComponent(detailsLayer);
wrapper.addComponent(wrappercontent);
。只要您想访问特定节点的邻接列表,就可以访问节点下的向量单元格。标识。
显然,这是一个基于邻接列表的解决方案。一般来说,这对于稀疏图来说是好事。可以这样想:如果你使用矩阵表示稀疏图,那么分配内存的很大一部分就不会被使用了。使用邻接图消除了这一点,但它消除了对任意边缘的持续访问时间。这意味着可以花费线性时间来检查给定边缘是否存在。话虽这么说,我不希望你在拓扑排序中使用该检查。但是,如果您选择使用矩阵,则仍需要将顶点映射到数字,以保留该部分。
最后但并非最不重要的是,您可以使用指针而不是整数ID。基本上你不会使用id在向量中查找顶点,但是你可以通过存储的指针直接访问顶点。您很可能仍需要字符串 - &gt;指针映射,至少对于图形创建。