本程序的主要难点在于,二叉排序树的删除。删除的结点有三种情况:
1.要删除的是叶结点。这种情况最简单,可以直接删除,然后再修改其父结点的指针置空即可。
2.如果要删除的结点只有一个孩子结点(该结点不一定是叶结点,可以是子树的根),删除之前需要改变父结点的指针,指向要删除结点的孩子结点。
3.如果要删除的结点有左右两棵子树,有两种选择:一、取其右子树中的最小元素。 二、取其左子树中的最大元素。将最小(大)元素的值赋给要删除的结点然后再删除最小(大)结点,这样就又回到了第二中情况只有一个孩子结点。因为不论是左子树的最大值还是右子树的最小值都只有一个孩子结点(否则就不符合最小或者最大了)。本程序采用的是找到左子树的最大值来替代被删除的值。
代码如下:
BSTree DeleteBSTree(BSTree bsTree, int x)
{
BSTree temp;
if (bsTree) //树不为空
{
if (x < bsTree->value)
{
bsTree->left = DeleteBSTree(bsTree->left, x); //从左子树递归删除
}
else if (x > bsTree->value)
{
bsTree->right = DeleteBSTree(bsTree->right, x); //从右子树递归删除
}
else //查找到了删除结点
{
/*当左右结点都存在时,一种是选择左子树的最大值,另一种是选择右子树的最小值*/
/*本文采用左子树的最大值*/
if(bsTree->left && bsTree->right)
{
/*找到左子树的的最大元素填充删除结点*/
temp = FindMaxBSTree(bsTree->left);
bsTree->value = temp->value;
/*从左子树中删除最大元素*/
bsTree->left = DeleteBSTree(bsTree->left, bsTree->value);
}
else /*被删除结点有一个或者没有结点*/
{
temp = bsTree;
if (!bsTree->left) //只有右孩子或者无子结点
{
bsTree = bsTree->right;
}
else //只有左孩子
{
bsTree = bsTree->left;
}
free(temp);
}
}
}
return