遍历二叉搜索树C ++

时间:2012-10-04 21:57:48

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

我正在编写一个编程任务并编写一堆函数来实现二叉搜索树,并给出了一些函数。我以为我理解了递归,但是如果你愿意,我会一直挂断转换方向。

以下是赋值的函数:

static void deleteAll(BSTNode<Data>* n) {
  if (0 == n) return;
  deleteAll(n->left);
  deleteAll(n->right);
  delete n;
}

要删除真正的短树,

    root
   /    \
lefty  righty

我致电deleteAll(root)n != 0现在我打电话给deleteAll(lefty)n != 0所以我致电deleteAll(lefty->left)。当然没有左节点。当我添加lefty节点时,我的构造函数将left,right和parent指针初始化为0,所以现在n == 0。所以我退出了这个功能,永远不会删除。我怎么去deleteAll(n->right)

正如我所说,提供此功能所以我不应该改变它。我想也许我必须打电话给deleteAll(b.begin())b.end()以从左侧或最右侧的节点开始,但每次我在脑海中经历它都会点击n == 0

请帮我理解。

2 个答案:

答案 0 :(得分:5)

想象一个箭头指向正在执行的当前行。当我们致电deleteAll(root)时,首先我们检查root是否为0:

--> if (0 == root) return;
    deleteAll(root->left);
    deleteAll(root->right);
    delete root;

由于root != 0,我们会调用deleteAll(root->left)

    if (0 == root) return;
--> deleteAll(root->left); /*
    |-1-> if (0 == lefty) return;
    |-2-> deleteAll(lefty->left);
    |-3-> deleteAll(lefty->right);
    |-4-> delete lefty; */
    deleteAll(root->right);
    delete root;
  }

现在箭头将向上移动到函数的顶部并开始对lefty执行相同操作,在我的注释中通过第1-4行(在第2行,同样的扩展将再次发生,直到找到一个空节点)。但重要的是它记住函数调用之前的位置,以便以后可以恢复。所以deleteAll(root->left)会去做它做的事情并最终回归。然后原始呼叫继续:

    if (0 == root) return;
    deleteAll(root->left);
--> deleteAll(root->right);
    delete root;

现在也删除了正确的节点。这种情况发生在递归的每一步。请记住,return仅返回当前函数,而不是整个递归链。

答案 1 :(得分:2)

返回仅返回调用它的函数。在deleteAll(lefty)的情况下(如果我理解正确,或者deleteAll(root))。 deleteAll(n->right)返回后会调用deleteAll(n->left)。 deleteAll的post条件是n,它的所有子节点都将被删除。

想象一下,我们有以下树:

    a
   / \
   b c
  /   \
 d     e

调用图如下:

deleteAll(a)
    deleteAll(a->left)
        deleteAll(a->left->left)
            deleteAll(a->left->left->left)
            deleteAll(a->left->left->right)
        deleteAll(a->left->right)
    deleteAll(a->right)
        deleteAll(a->right->left)
        deleteAll(a->right->right)
            deleteAll(a->right->right->left)
            deleteAll(a->right->right->right)

或者就节点名称而言:

deleteAll(a)
    deleteAll(b)
        deleteAll(d)
            deleteAll(NULL)
            deleteAll(NULL)
        deleteAll(NULL)
    deleteAll(c)
        deleteAll(NULL)
        deleteAll(e)
            deleteAll(NULL)
            deleteAll(NULL)