迭代后序遍历 BST
iterative postorder traverse bst?
我有两个问题,1)对于任何递归算法,都存在一个迭代算法,对吗?我认为这是正确的,因为您只需要显式使用堆栈即可。并在这个问题中得到了证实 从递归到迭代的方式
2)可能与上述问题相同,我真的不认为迭代解决方案是显而易见的或即使使用递归算法也很容易编写。例如:对于后序 (LRN) 或无序 (LNR) BST 遍历,如何使用迭代方法编写它?在这两种情况下,要找到要插入到堆栈中的第一个对象并不容易。这就是我卡住的地方。
有什么建议吗?实际上,我的目的与上述问题相同,尝试找到一种通用模式将递归算法更改为迭代算法。
我觉得你没有正确地问这个问题。我将尝试回答关于如何考虑实现有序遍历的迭代版本的问题(我只是碰巧对此进行了一些思考并在最近实现了它。我觉得我也会通过放下这个来帮助自己)因为人们知道递归版本。
递归版本中的每个函数调用都寻求访问与函数调用关联的节点。该函数被编码为与节点对应的激活帧被保存到系统堆栈(该进程的堆栈区域)上,然后它才能完成其主要工作,即访问节点。之所以如此,是因为我们想在访问节点本身之前访问节点的左侧子树。
访问左侧子树后,返回到我们保存的节点的框架会导致语言环境从内部堆栈弹出相同的内容,现在允许访问我们的节点。
我们必须用明确的堆栈来模仿这种推动和弹出。
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;
}
}
}
理解这一点的最好方法是在每次调用和返回递归版本时在纸上绘制内部堆栈的功能。
相关文章:
- 有什么方法可以遍历结构吗
- 在循环中按顺序遍历成员变量
- 遍历模板参数
- 在遍历处理程序的向量时注册和注销处理程序
- C++RapidXml-使用first_node()遍历以修改XML文件中节点的值
- 遍历并行数组以确定C++中的最大数字
- 遍历顺序由 std::文件系统directory_iterator给出
- 遍历链表时的无限循环
- 遍历unordered_map向量
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- C++声明双链表,使用两个 for 循环双向遍历列表并打印
- 通过摩尔斯电码BST预购遍历
- 使用无序遍历从相同大小的排序数组填充现有 BST
- 在c++中使用按顺序遍历的BST中节点的秩
- 使用递归的BST顺序遍历
- 测试二叉搜索树(BST)的遍历
- 数组遍历中的BST
- 遍历BST时出现Stackoverflow异常
- 遍历BST并输出到队列的前缀
- 迭代后序遍历 BST