C++ 非递归后序图遍历?
我正在寻找一些伪代码、算法或指南,它们将帮助我为广义图数据结构找到合适的迭代后序遍历算法 我发现了大量的资源(如两堆栈或一堆栈算法),它们可以很好地处理树,但对于图来说,它们无法处理循环/后边缘、交叉边缘等 我已经成功地编写了递归后序图遍历算法,如下所示:C++ 非递归后序图遍历?,c++,recursion,tree,iteration,graph-theory,C++,Recursion,Tree,Iteration,Graph Theory,我正在寻找一些伪代码、算法或指南,它们将帮助我为广义图数据结构找到合适的迭代后序遍历算法 我发现了大量的资源(如两堆栈或一堆栈算法),它们可以很好地处理树,但对于图来说,它们无法处理循环/后边缘、交叉边缘等 我已经成功地编写了递归后序图遍历算法,如下所示: template<typename V, typename E> void tGraph<V, E>::RecursivePostOrderSearch(const tGraph& g, const Verte
template<typename V, typename E>
void tGraph<V, E>::RecursivePostOrderSearch(const tGraph& g, const VertexType& u, std::set<VertexType>& visited, std::vector<VertexType>& result)
{
if (visited.find(u) == visited.end())
{
visited.insert(u);
EdgeSet edgesOut = g.outgoingEdgesOf(u);
for(typename EdgeSet::const_iterator iter = edgesOut.begin(); iter != edgesOut.end(); iter++)
{
RecursivePostOrderSearch(g, iter->second.second, visited, result);
}
result.push_back(u);
}
}
template<typename V, typename E> std::vector<V> tGraph<V, E>::postOrderList(const VertexType& v) const
{
std::set<V> visited;
std::vector<V> result;
RecursivePostOrderSearch(*this, v, visited, result);
return result;
}
模板
void tGraph::RecursivePostOrderSearch(常量tGraph&g、常量VertexType&u、std::set&visted、std::vector&result)
{
if(visted.find(u)=visted.end())
{
插入(u);
EdgeSet edgesOut=g.伸出量(u);
对于(类型名EdgeSet::const_迭代器iter=EdgeOut.begin();iter!=EdgeOut.end();iter++)
{
递归PostOrderSearch(g,iter->second.second,已访问,结果);
}
结果:推回(u);
}
}
模板std::vector tGraph::postOrderList(const VertexType&v)const
{
std::访问的集合;
std::向量结果;
递归PostOrderSearch(*this,v,visted,result);
返回结果;
}
其中,V
是节点类型,E
是边缘类型——一对“权重”和传入/传出节点对
如果我在下图上运行::postOrderList
(根节点A
):
我希望按此顺序获得以下节点(边按其权重的顺序排列):
,D
,E
,F
,B
,G
,C
A
提前感谢。结果有问题,但可以通过处理每个节点两次来处理。请使用标志指定是要访问子节点还是要将其推回 要实现这一点,您可以使用堆栈/向量以及包含“u”和bool(用于标志)的结构 大致如下:
template<typename V, typename E>
void tGraph<V, E>::PostOrderSearch(const tGraph& g, const VertexType& u, std::set<VertexType>& visited, std::vector<VertexType>& result)
{
std::vector<std::pair<VertexType,bool> > stack;
stack.push_back(std::pair<VertexType, bool>(u,false));
for(;;) {
if (stack.empty()) return; // Done.
std::pair<VertexType, bool> item=stack.back();
stack.pop_back();
VertexType u=item.first;
if (item.second) {
// Post-visit
result.push_back(u);
}
else if (visited.find(u)==visited.end()) {
// Add in reverse order, due to stack
visited.insert(u);
EdgeSet edgesOut = g.outgoingEdgesOf(u);
stack.push_back(std::pair<VertexType, bool>(u,true));
for(typename EdgeSet::const_reverse_iterator iter = edgesOut.rbegin(); iter != edgesOut.rend(); iter++)
{
stack.push_back(std::pair<VertexType,bool>(iter->second.second,false));
}
}
}
模板
void tGraph::PostOrderSearch(const tGraph&g、const VertexType&u、std::set&visted、std::vector&result)
{
std::向量堆栈;
stack.push_back(std::pair(u,false));
对于(;;){
if(stack.empty())返回;//完成。
std::pair item=stack.back();
stack.pop_back();
VertexType u=项目优先;
如果(第二项){
//访问后
结果:推回(u);
}
else if(visted.find(u)=visted.end()){
//由于堆栈原因,按相反顺序添加
插入(u);
EdgeSet edgesOut=g.伸出量(u);
stack.push_back(std::pair(u,true));
对于(类型名称EdgeSet::const_reverse_iterator iter=edgesOut.rbegin();iter!=edgesOut.rend();iter++)
{
stack.push_back(std::pair(iter->second.second,false));
}
}
}
非常感谢。这很有效;我想我知道我错在哪里了。在解决这个问题的尝试中,我尝试使用std::set
来标记节点,类似于我对访问的集所做的操作。但是,我没有想到最好用bool标记节点,将其推到堆栈上,然后处理bool作为一种操作码——现在我看到你是如何实现它的,这就更有意义了。再次感谢你。我真的很感谢你的帮助。