微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

迭代后置遍历BST?

如何解决迭代后置遍历BST?

| 我有两个问题, 1)对于任何递归算法,都有一个迭代算法,对吗?我认为这是正确的,因为您只需要显式使用堆栈即可。此问题已得到证实  从递归到迭代的方法 2)可能与上述问题相同,即使使用递归算法,我也不认为迭代解决方案是显而易见的或易于编写的。例如:对于后置(LRN)或inorder(LNR)遍历,如何用迭代方法编写?在这两种情况下,要找到要插入堆栈的第一个对象并不容易。那就是我被困住的地方。 有什么建议么?实际上,我的目的与上述问题相同,尝试找到一种将递归算法更改为迭代算法的通用模式。     

解决方法

我觉得您没有正确提出这个问题。我将尝试回答有关如何考虑实现有序遍历的迭代版本的问题(我刚好考虑了一下并在不久前实现了它。我觉得我也可以通过降低这一点来帮助自己),因为您知道递归版本。 递归版本中的每个函数调用都试图访问与该函数调用关联的节点。对功能进行编码,使得与节点相对应的激活帧在其可以完成其主要工作(即访问该节点)之前保存到系统堆栈(该进程的堆栈区域)中。之所以这样,是因为我们要在访问节点本身之前先访问节点的左子树。 在访问了左子树之后,返回到我们保存的节点的框架会导致语言环境从内部堆栈中弹出该语言环境,现在允许访问我们的节点。 我们必须使用显式堆栈来模拟这种推送和弹出。
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;
        }
    }
}
理解这一点的最好方法是在每次调用并返回递归版本时在纸上绘制内部堆栈的功能。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。