【问题标题】:iterative postorder traverse bst?迭代后序遍历 bst?
【发布时间】:2011-08-31 17:21:41
【问题描述】:

我有两个问题, 1)对于任何递归算法,都存在迭代算法,对吗?我认为这是正确的,因为您只需要显式使用堆栈即可。并且在这个问题中得到了证实 Way to go from recursion to iteration

2) 可能和上面的问题一样,我真的不认为迭代解决方案是显而易见的或即使使用递归算法也不容易编写。例如:对于后序(LRN)或中序(LNR)bst traverse,你怎么能用迭代的方法来写呢?在这两种情况下,要找到第一个插入堆栈的对象并不容易。这就是我卡住的地方。

有什么建议吗?其实我的目的和上面的问题是一样的,试着找到一个通用的模式,把递归算法改成迭代算法。

【问题讨论】:

  • 1) 是的。 2)我相信你链接到的问题已经回答了你自己的问题。请仔细阅读那边的答案。
  • 那么您的实际问题是什么?仅搜索迭代树遍历就会提供一堆链接,也在 wikipedia 上。

标签: c++ recursion binary-search-tree iteration


【解决方案1】:

我觉得你没有正确地提出这个问题。我将尝试回答关于如何考虑实现中序遍历的迭代版本的问题(我只是碰巧对此进行了一些思考并在最近实现了它。我觉得我也会通过放下它来帮助自己) 假设一个人知道递归版本。

递归版本中的每个函数调用都试图访问与函数调用关联的节点。该函数的编码使得与节点对应的激活帧在它可以执行其主要工作(即访问该节点)之前被保存到系统堆栈(该进程的堆栈区域)中。这是因为我们想在访问节点本身之前访问节点的左子树。

访问左子树后,返回到我们保存的节点的框架会导致语言环境从内部堆栈中弹出相同的内容,现在允许访问我们的节点。

我们必须使用显式堆栈来模拟这种推送和弹出操作。

template<class T>
void inorder(node<T> *root)
{
    // The stack stores the parent nodes who have to be traversed after their
    // left sub-tree has been traversed
    stack<node<T>*> s;

    // points to the currently processing node
    node<T>* cur = root;

    // Stack-not-empty implies that trees represented by nodes in the stack
    // have their right sub-tree un-traversed
    // cur-not-null implies that the tree represented by 'cur' has its root
    //   node and left sub-tree un-traversed
    while (cur != NULL || !s.empty())
    {
        if (cur != NULL)
        {
            for (; cur->l != NULL; cur = cur->l) // traverse to the leftmost child because every other left child will have a left subtree
                s.push(cur);
            visit(cur); // visit him. At this point the left subtree and the parent is visited
            cur = cur->r; // set course to visit the right sub-tree
        }
        else
        {// the right sub-tree is empty. cur was set in the last iteration to the right subtree
            node<T> *parent = s.top();
            s.pop();
            visit(parent);
            cur = parent->r;
        }
    }
}

理解这一点的最好方法是在每次调用和返回递归版本时在纸上画出内部堆栈的功能。

【讨论】:

    猜你喜欢
    • 2016-12-15
    • 1970-01-01
    • 2014-08-26
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多