非递归的后序图遍历?

时间:2018-06-01 14:07:54

标签: c++ recursion tree iteration graph-theory

我希望找到一些伪代码,算法或指南来帮助我找到适用于广义图数据结构的迭代后序遍历算法。

我发现很多资源(比如两个堆栈或一个堆栈算法)可以很好地处理树木,但是因为它们不能处理周期/后边缘,交叉边缘等等而分解图形

我已经成功编写了一个递归的后序图遍历算法,如下所示:

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;
}

V是节点类型,E是边缘类型 - &#34;权重&#34;和传入/传出节点对。

如果我在下图中运行::postOrderList(使用根节点A):

undirected graph in question

我希望按此顺序获得以下节点(边缘按其重量顺序排列):

  • DEFBGCA

...上面我的递归算法确实提供了正确的结果。

然而,尝试将其转换为迭代算法一直是我自己的挑战,而且我没有取得任何成功。我尝试过转换为尾递归,然后我可以转换为迭代,但我无法弄清楚。我也试图转换基于树的双栈和单栈算法,但我也无法正确复制结果。

我已经看到类似的堆栈溢出问题,但似乎没有一个覆盖实际的迭代算法,伪代码或递归到这种算法的迭代转换,所以我认为在这方面的任何指导都会有所帮助。

提前致谢。

1 个答案:

答案 0 :(得分:1)

result.push_back存在问题,但可以通过处理每个节点两次来处理,使用标志来指定您是想要访问子节点还是将其推回。

为了实现你可以使用带有&#34; u&#34;的结构的堆栈/向量。和一个布尔(为国旗)。

这些方面的东西:

^      begining of the string
[^-]*  all characters except - zero or more times
\-     literal -
[^-]*  all characters except - zero or more times
$      end of the string