【发布时间】:2013-07-06 23:07:48
【问题描述】:
我正在尝试从我的 BST 中删除根节点,然后打印树 inorder。根删除似乎是一个问题,所有其他节点都已成功删除。
根是 20。
按顺序打印 5 6 7 8 9 10 17 18 20 23 24 25 29 55 56 57 58 59
提供要删除的节点
20
删除后
5 6 7 8 9 10 17 18 20 5 6 7 8 9 10 17 18 23 24 25 29 55 56 57 58 59
正如您在删除后看到的那样,bintree 并不像预期的那样。粗体键是不需要的。 下面是我的代码
void treeDeleteNode (binTreeT **tree, binTreeT *node)
{
binTreeT *succs;
binTreeT *parent;
binTreeT *root = *tree;
if (node->rchild == NULL) {
transplantTree (&root, node, node->lchild);
}
else if (node->lchild == NULL) {
transplantTree (&root, node, node->rchild);
}
else {
succs = treeMin (node->rchild);
parent = getParentNode (root, succs);
if (parent != node) {
transplantTree (&root, succs, succs->rchild);
succs->rchild = node->rchild;
}
transplantTree (&root, node, succs);
succs->lchild = node->lchild;
}
}
void transplantTree (binTreeT **root, binTreeT *old, binTreeT *new)
{
binTreeT *rootRef = *root;
binTreeT *parent;
parent = getParentNode(rootRef, old);
if (NULL == parent) {
*root = new;
}
else {
if (parent->lchild == old) {
parent->lchild = new;
}
else {
parent->rchild = new;
}
}
}
binTreeT* treeMin (binTreeT *tree)
{
while (tree->lchild != NULL) {
tree = tree->lchild;
}
return tree;
}
binTreeT* getParentNode(binTreeT *root, binTreeT* node)
{
binTreeT *parent = NULL;
while (root->data != node->data) {
parent = root;
if (node->data < root->data) {
root = root->lchild;
}
else if(node->data > root->data) {
root = root->rchild;
}
}
return parent;
}
void inOrderPrint (binTreeT *tree)
{
if (NULL != tree) {
inOrderPrint (tree->lchild);
printf("%d \t", tree->data);
inOrderPrint (tree->rchild);
}
}
.....任何帮助表示赞赏.....
【问题讨论】:
-
你能解释一下你的算法吗?
-
是的。函数“treeDeleteNode (binTreeT **tree, binTreeT *node)”将主 BST(树)和要删除的节点(节点)作为输入参数。如果要删除的节点有 2 个子节点,root=20 的情况下获取节点函数 treeMin 的后继,此时 succs=23 获取后继的父 getParentNode 输入 args 主树和后继 parent=20 如果后继的父是要删除的节点(successor has left child NULL) 用它的后继替换要删除的节点移植Tree(&root, node, succs)
-
contd: and make (succs key=23) succs->lchild = node->lchild .. 在这种情况下 node 是 root 并且 node->lchild is = 17 //下面的代码不会如果后继者的父节点不是要删除的节点,则在删除 root=20 时被命中然后 if (parent != node) { 用主树中的右子节点替换 (transplantTree) 使 succs-> 右子节点指向node->rchild(必须删除节点)现在替换(transplantTree)主树中要被后继删除的节点,并使succ-> lchild指向node-> lchild。
标签: c binary-search-tree