递归如何适用于此二叉搜索树算法

时间:2017-11-11 09:22:43

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

我有以下二进制搜索树,有根节点20.我试图回答的问题是,如果我们应用函数t = deleteRoot(t),那么新根节点的值也是如此作为其直接的左右儿童(例如,当前的根节点是20,左边的孩子11和右边的孩子32)。在过去的两个小时里,我试图解决这个问题,至少写了10页,但这次递归正在扼杀我。有人可以帮助我想象这一点 - 即一些思考方式,让我可以处理递归。我不太擅长可视化递归如何工作,但我可以在某种程度上实现它。非常感谢。顺便说一句,答案是根节点:21,左子11和右子32。 enter image description here

我的尝试:

问题告诉我们从t=deleteRoot(t)开始。

parent = node containing 25 
succ = node containing 21
succval = 21
然后我们到达

t = TreeDelete(t, succval)

然后我对TreeDelete函数如何工作有点迷失

t->left = TreeDelete(t->left, key) ...etc

deleteRoot(树t)功能

// delete root of tree
Tree deleteRoot(Tree t)
{
    Link newRoot;
    // if no subtrees, tree empty after delete
    if (t->left == NULL && t->right == NULL) {
        free(t);
        return NULL;
    }
    // if only right subtree, make it the new root
    else if (t->left == NULL && t->right != NULL) {
        newRoot = t->right;
        free(t);
        return newRoot;
    }
    // if only left subtree, make it the new root
    else if (t->left != NULL && t->right == NULL) {
        newRoot = t->left;
        free(t);
        return newRoot;
    }
    // else (t->left != NULL && t->right != NULL)
    // so has two subtrees
    // - find inorder successor (grab value)
    // - delete inorder successor node
    // - move its value to root
    Link parent = t;
    Link succ = t->right; // not null!
    while (succ->left != NULL) {
        parent = succ;
        succ = succ->left;
    }
    int succVal = succ->value;
    t = TreeDelete(t,succVal);
    t->value = succVal;
    return t;
}

树TreeDelete(树t,密钥k)功能:

Tree TreeDelete(Tree t, Key k)
{
    Tree deleteRoot(Tree);

    if (t == NULL)
        return NULL;
    int diff = cmp(k,key(t->value));
    if (diff == 0)
        t = deleteRoot(t);
    else if (diff < 0)
        t->left = TreeDelete(t->left, k);
    else if (diff > 0)
        t->right = TreeDelete(t->right, k);
    return t;
}

2 个答案:

答案 0 :(得分:1)

  

顺便说一下,答案是根节点:21,左子11和右子32。

嗯,它是一个解决方案,但不是唯一的解决方案。

左边的孩子11和右边的孩子32也是一个解决方案。

删除根时,可以选择新根

  1. 左子树中的最高数字
    1. 右子树中的最小数字
    2. 因此,将所选节点的值复制到当前根目录。然后删除所选节点。如果所选节点有子节点,则可以递归重复该过程。

答案 1 :(得分:1)

在删除的情况下,如果要删除的节点有两个子节点:

  • 找到继任者或前任
  • 用继承者/前任者的内容替换节点
  • 对后继者/前任者进行调用删除(这样会减小大小)
  • 返回节点

后继是右子树中的最高元素,而前一个是左子树中的最低元素。在你的情况下,继任者将是21,而前任将是18。