1

我正在做一个编程作业并编写一堆函数来实现二叉搜索树,并给出了一些函数。我以为我理解递归,但如果你愿意的话,我一直对切换方向感到困惑。

这是分配给定的函数:

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

要删除一棵非常短的树,

    根
   / \
左右右

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

正如我所说,提供了此功能,因此我不应该更改它。我想也许我必须调用deleteAll(b.begin())b.end()从最左边或最右边的节点开始,但每次我在脑海中通过它时,我都会点击n == 0.

请帮我理解。

4

2 回答 2

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只返回当前函数,而不是整个递归链。

于 2012-10-04T22:11:19.113 回答
2

return 只返回到调用它的函数。在这种情况下deleteAll(lefty)(如果我理解正确,那或deleteAll(root))。deleteAll(n->right)返回后会被调用deleteAll(n->left)。deleteAll 的后置条件是删除 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)
于 2012-10-04T22:02:33.400 回答