这篇博客接着上篇博客,主要讲二叉树搜索树的删除操作。
如上图,对一个二叉搜索树进行删除操作要分情况讨论。
1.要删除的节点没有左右孩子,(如图中的0,或者9);
2.要删除的节点有左孩子,没右孩子(如图中的1);
(1)要删除的节点是根节点;
(2)要删除的节点不是根节点;
3.要删除的节点没有左孩子,有右孩子(如图中的8);
(1)要删除的节点是根节点;
(2)要删除的节点不是根节点;
4.要删除的节点有左孩子,也有右孩子;
(图2)
(1)要删除的节点是根节点
【1】在其右子树中寻找最小的节点temp,将temp的key和value赋给,要删除 的节点pro,删除temp;(如图2)
~1.temp有右孩子。(需要其双亲节点pParent,将pParent的左孩子指向temp 的右孩子,然后free);
~2.temp没有右孩子。(直接【1】);
(2)要删除的节点不是根节点。
【1】pro的右孩子temp有左孩子,没有右孩子(如图3);
(图3)
【2】pro的右孩子temp没有左孩子,有右孩子;(如图4)
(图4)
【3】pro的右孩子temp没有左孩子,没有右孩子;
代码如下:
bool Delete_node(pTreeNode proot, int key)
{
if(proot == NULL)
return false;
if(!find(key))
return false;
pTreeNode pro = proot;
pTreeNode pParent = NULL;
while(pro)
{
if (NULL != pro && pro->key == key)
{
break;
}
if (NULL != pro && pro->key < key)
{
pParent = pro;
pro = pro->pright;
}
if (NULL != pro && pro->key > key)
{
pParent = pro;
pro = pro->pleft;
}
}
//第一种情况:没有孩子节点
if (pro->pleft == NULL && pro->pright == NULL)
{
free(pro);
pro = NULL;
pParent->pleft = NULL;
pParent->pright = NULL;
return true;
}
//2.有左孩子,没有右孩子
if (pro->pleft != NULL && pro->pright == NULL)
{
//如果根节点
if (pro == proot)
{
pro->pleft = proot;
free(pro);
return true;
}
else
{
pParent->pleft = pro->pleft;
free(pro);
pro = NULL;
return true;
}
}
//没有左孩子,有右孩子
if (pro->pleft == NULL && pro->pright != NULL)
{
//如果根节点
if (pro == proot)
{
pro->pright = proot;
free(pro);
return true;
}
else
{
pParent->pright = pro->pright;
free(pro);
pro = NULL;
return true;
}
}
//有左孩子,也有右孩子
if (pro->pleft != NULL && pro->pright != NULL)
{
pTreeNode temp = pro->pright;
pTreeNode pp = NULL;
if (temp->pleft == NULL && temp->pright != NULL)
{
pParent->pright = temp;
temp->pleft = pro->pleft;
free(pro);
pro = NULL;
}
else if(temp->pleft == NULL && temp->pright == NULL)
{
pParent->pleft = temp;
temp->pleft = pro->pleft;
free(pro);
pro = NULL;
}
else
{
while (temp->pleft != NULL)
{
pp = temp;
temp = temp->pleft;
}
if(temp->pright == NULL)
{
pro->data = temp->data;
pro->key = temp->key;
free(temp);
temp = NULL;
}
else
{
pp->pleft = temp->pright;
pro->data = temp->data;
pro->key = temp->key;
free(temp);
temp = NULL;
}
}
}
}