【问题标题】:Non-recursive destructor binary search tree USING A STACK使用堆栈的非递归析构二叉搜索树
【发布时间】:2013-04-21 10:20:22
【问题描述】:

我正在考虑使用一堆二进制节点指针创建一个非递归析构函数。这段代码会运行吗?

binaryNode* parent = root;
while (!empty())
{
  if (parent->left)
  {
    stack1.push(parent)
    parent = parent->left;
  }
  else if (parent->right)
  {
    stack1.push(parent)
    parent = parent->right;
  } else 
  {
    delete parent;
    parent = stack1.pop();
  }
}

我还没有完成基本程序,所以上面的代码没有经过测试。我觉得应该没什么问题。虽然它没有经过测试运行,但我跟踪了一个二叉搜索树,它运行得很好。另外,我在 stackoverflow 中找不到具有二叉搜索树遍历的堆栈实现。

【问题讨论】:

  • 有什么问题?如果你只是想知道它是否有效,编译它并测试它。

标签: c++ search stack binary-tree binary-search-tree


【解决方案1】:

在我看来,您的代码中似乎有很多问题,但也很难确定您在实现代码时的意图是什么(即哪些问题是 C++ 的问题,哪些是问题带有“设计级”伪代码)。代码中的一个问题是delete parent 只释放parent 引用的对象所占用的空间。因此,当您弹出堆栈时,您最终可能会重新执行 if (parent->left) 分支,因此 delete 再次执行相同的对象。而你似乎只是delete 叶节点。

我遇到的最大问题是您的算法设计不明确。获得基于堆栈的递归算法版本的常用方法是首先获得递归版本(至少在纸上),然后分解递归。在这种情况下,您的标准post-order traversal,实现为对do_action 的调用,下面带有node = root,类似于

do_action(node)
    if node has left descendant
        do_action(left descendant)
    if node has right descendant
        do_action(right descendant)
    perform action on node

在您的情况下,action 是删除节点。现在,您可以在没有显式递归的情况下实现这一点(正如Non recursive Depth first search algorithm 的答案所示,这对于某些树遍历问题可能非常简单)。但是,在这种情况下您为什么要这样做是有争议的?递归调用使用程序自己的堆栈,而您希望使用自己的数据结构隐式递归。只是在去掉tail end recursion的情况下,优点是非黑即白的,因为这里真正消除了递归,而不是用堆栈模拟。

如果您确实采用了删除递归的方法,那么您的代码似乎会变得非常丑陋:请参阅 http://leetcode.com/2010/10/binary-tree-post-order-traversal.htmlNon-recursive post order traversal。您的隐式递归代码在时间和/或空间上的性能可能会比原始的显式递归代码更差。它肯定有更多的错误!

【讨论】:

    猜你喜欢
    • 2013-04-21
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 2014-01-02
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多