对于二叉树的删除操作来说,存在三种情况
**1.**当删除节点为叶节点的时候,此时将节点置为空
**2.**当删除节点为根节点且该根节点只有一个子树的时候,此时需要替换掉删除元素,最后再进行释放
**3.**当删除节点为根节点且根节点存在两个子树的时候,此时我们可以选择替换左子树的最大元素,或者右子树的最小元素
C代码如下
Tree de_tree(Item data, Tree t) //二叉树元素的删除
{
Tree parent; //根节点
Tree curTree; //现在的节点
Tree fTree = t; //找到的节点位置
while (fTree)
{
if (data == fTree->element) //找到元素则退出
break;
else if (data < fTree->element) //如果元素小于当前元素 则向左查找
{
parent = fTree;
fTree = fTree->lchild;
}
else
{ //否则向右查找
parent = fTree;
fTree = fTree->rchild;
}
}
if (!fTree) //如果没有找到要删除的元素的话 直接返回t
return t;
///删除的第一种情况 当找到的元素为叶节点的时候
if (!fTree->lchild && !fTree->rchild)
{
if (fTree == t) //表示该树只有一个根节点
{
t = NULL; //将根节点置为NULL
free(fTree);
}
else if (fTree == parent->lchild) //该叶节点为左子树
{
parent->lchild = NULL; //左子树置为NULL
free(fTree);
}
else
{ //该叶节点为左子树
parent->rchild = NULL; //右子树置为NULL
free(fTree);
}
return t;
}
///删除的第二种情况 左子树或右子树为空
else if (!fTree->lchild || !fTree->rchild)
{
if (fTree == parent->lchild) //如果当前要删除的节点是父节点的左子树的时候
{
if (fTree->lchild) //删除的节点只有一个左子树
parent->lchild = fTree->lchild; //那么跳过要删除的节点并替换为下个左子树
else //删除的节点只有一个右子树
parent->lchild = fTree->rchild; //替换为下个右子树
}
else
{ //如果当前要删除的节点是父节点的右子树的时候
if (fTree->lchild) //只有一个左子树
parent->rchild = fTree->lchild;
else //只有一个右子树
parent->rchild = fTree->rchild;
}
free(fTree);
return t;
}
///删除的第三种情况 也就是当左子树和右子树都不为空的情况下进行删除
///此时可以选择将删除元素替换为左子树的最大值和右子树的最小值
else
{
parent = fTree;
curTree = fTree->lchild; //此处我们选择左子树的最大值
while (curTree->rchild) //找到最右下角的位置,也就是左子树中的最大值
{
parent = curTree; //每次向下寻找
curTree = curTree->rchild;
}
fTree->element = curTree->element; //交换最大值
if (parent == fTree) //表示左子树的最大值为要删除元素的左子树
parent->lchild = curTree->lchild; //跳过该元素
else
parent->rchild = curTree->lchild; //因为已经交换了最大值,那么我们就需要跳过该节点
free(curTree);
return t;
}
}
代码已经很详细的解释了如何进行操作的,祝大家学习顺利!