节点删除
二叉搜索树节点的删除分为三种情况分别是:
第二种情况:
第三种情况:
代码实现
void Get_Father_node(Bin_T* T, Bin_T* child_node, Bin_T** father_node)
{
if(T!=NULL)
{
if(T->left == child_node || T->right == child_node)
{
*father_node = T;
return;
}
else
{
Get_Father_node(T->left, child_node,father_node);
Get_Father_node(T->right, child_node,father_node);
}
}
}
//节点的删除,是真的麻烦
void Binary_tree_delete_node(Bin_T* T, Bin_T* temp, int num)
{
if(T == NULL)
{
printf("tree is empty\n");
return;
}
else
{
if (T->data == num && T == temp)//如果要删除的是头节点
{
}
else if(num > T->data)
{
Binary_tree_delete_node(T->right,temp, num);
}
else if(num < T->data)
{
Binary_tree_delete_node(T->left,temp, num);
}
else //找到该值
{
if(T->left == NULL && T->right == NULL)//如果是叶节点
{
Bin_T* father_node = NULL;
Get_Father_node(temp, T,&father_node);//第一个参数永远在根的位置,T为找到的节点位置
if(father_node->left == T)
{
father_node->left = NULL;
free(temp);
}
else if(father_node->right == T)
{
father_node->right = NULL;
free(temp);
}
}
else if(T->left == NULL || T->right == NULL) //如果有一个子节点
{
if(T->left == NULL&& T->right!=NULL)//左边是空的,那我们使用右边
{
Bin_T* father_node = NULL;
Get_Father_node(temp, T, &father_node);
father_node->right = T->right;
free(T);
}
else if(T->left != NULL && T->right == NULL)//右边是空的,使用左边的子节点
{
Bin_T* father_node = NULL;
Get_Father_node(temp, T, &father_node);
father_node->left = T->left;
free(T);
}
}
else// 使用左子树最右边的节点
{
Bin_T* ptr = T->left;
while(ptr->right!=NULL)
{
ptr = ptr->right;
}
T->data = ptr->data;
//找到ptr的父节点
Bin_T* father_node = NULL;
Get_Father_node(temp, ptr, &father_node);
if(father_node->right == ptr && ptr->left != NULL)
{
father_node->right = ptr->left;
free(ptr);
}
else
{
father_node->right = NULL;
free(ptr);
}
}
}
}
}