接上一篇插入之后,又折腾写了AVL递归删除例程,主要难点在于删除后保证路径上的节点高度值有效。思路已在例程中说明参考了http://www.cnblogs.com/skywang12345/p/3576969.html,该文章中的删除例程未考虑删除之后恢复高度值,导致删除节点后失衡。后又参考了http://www.cppblog.com/cxiaojia/archive/2015/07/20/187776.html,该文章为C++实现。
AvlTree Delete(int X, AvlTree T)
{
if (NULL == T)
{
return T;
}
if (X < T->Element)
{
T->Left = Delete(X, T->Left);
/** 若失衡,调整平衡 */
if (Height(T->Right) - Height(T->Left) == 2)
{
Position P = T->Right;
if (Height(P->Left) <= Height(P->Right))
{
T = SingleRotateWithRight(T);
}
else
{
T = DoubleRotateWithRight(T);
}
}
}
else if (X > T->Element)
{
T->Right = Delete(X, T->Right);
/** 若失衡,调整平衡 */
if (Height(T->Left)-Height(T->Right) == 2)
{
Position P = T->Left;
if (Height(P->Left) <= Height(P->Right))
{
T = SingleRotateWithLeft(T);
}
else
{
T = DoubleRotateWithLeft(T);
}
}
}
else //X == T->Element
{
/**
* 1. 左右子树均不为空:
* 若左子树较高
* (1)替换节点element为左子树最大节点element
* (2)循环删除最大节点
* 若右子树较高或等高
* (1)替换节点element为右子树最小节点element
* (2)循环删除最小节点
* 2. 左右子树至少有一个为空
* 若左子树为空
* (1)删除当前节点并返回右子树
* 若右子树为空
* (2)删除当前节点并返回左子树
*/
if ((NULL != T->Left) && (NULL != T->Right))
{
if (Height(T->Left) > Height(T->Right))
{
AvlTree maxNode = FindMax(T->Left);
T->Element = maxNode->Element;
T->Left = Delete(maxNode->Element, T->Left);
}
else
{
AvlTree minNode = FindMin(T->Right);
T->Element = minNode->Element;
T->Right = Delete(minNode->Element, T->Right);
}
}
else
{
AvlTree tmp = T;
T = NULL != T->Left ? T->Left : T->Right;
free(tmp);
}
}
/** 高度值需在上一级修改 */
if (NULL != T)
{
T->Height = MAX(Height(T->Left), Height(T->Right)) + 1;
}
return T;
}