我正在尝试将深度优先搜索作为一个函数来实现,它接受一个图形并输出DFS。
class Graph
{
private:
int V;
int timestamp;
std:: vector<std:: list<int> > graph;
std:: map<int, vertex> nodemap;
public:
Graph(int V);
int Size();
void addEdge(int u, int v);
void printEdges();
void printVertices();
};
上面是我为图表制作的课程。我正在尝试创建一个函数,返回指向私有向量和映射的指针,以便在图的邻接列表和地图数据结构上执行for循环操作。然而,我知道直接操作数据结构是对封装的违反,我想维护我的程序的面向对象的规则。如何才能做到这一点而不违反封装呢?
PS:,我不希望使用朋友函数,因为我不想让这个函数成为例外。我想找到一个主流的解决方案,它是程序员普遍使用的,是一个有纪律的解决方案。不过,如果需要,我可以更改我的类字段/可访问性。
谢谢您抽时间见我!
发布于 2016-05-18 00:26:44
如果您需要在邻接映射上迭代,则添加一个成员函数,允许您这样做。
你有两个明显的选择:
begin()
/ end()
。第一个应该是这样的:
for(auto it = graph.adjacency_begin() ; it!=graph.adjacency_end(); ++it) {
vertex& v1 = it->v1;
vertex& v2 = it->v2;
...
}
第二个看起来就像
graph.for_each_adjacency(
[](vertex& v1, vertex &v2) { .... }
);
最大的问题是如何在迭代期间处理图形结构的更改。我看到的大多数实现要么显式地不允许这样做(要么抛出异常,要么声明这样做是未定义的行为),或者在内部副本上操作迭代。如果你需要一些不同的东西--期待它成为未来的一个痛点。
如果您想在不允许在循环中进行更新的循环中执行某些更新,只需循环将所需的更新存储在某个地方,那么在循环完成后应用所有更新:
std::vector<UpdateInfo> updates;
graph.for_each_adjacency( [&updates](const vertex& v1, const vertex& v2) {
updates.push_back( calculateUpdate(v1,v2) );
} );
foreach(updates, [&graph](const UdpateInfo &update) {
applyUpdate(update, graph);
} );
发布于 2016-05-18 00:23:51
你应该决定你是否是“面向对象的”。如果没有,那么您就有了一个结构(也就是记录),所以让您的字段公开并继续进行。但如果你是O-O还有几条路要走。您可以在Graph
上提供访问器,例如,给定顶点返回边(或相邻顶点)的访问器。然后,在图的外部编写遍历算法。或者,您可以将遍历算法作为Graph
的一种方法,并且它可以直接访问私有成员。
https://stackoverflow.com/questions/37288163
复制相似问题