平衡二叉树的删除

在删除某节点之前我们需要找到该节点的位置,因此寻找节点的过程可分为以下3种情况(假设我们要找的节点值为data,当前节点为note):

1、note的值<data,则应该在该节点的左子树寻找。在左子树中删除该节点成功后,需要调整平衡二叉树,以保持平衡。如果删除节点后(在左子树中删除节点,左子树高度不变或变矮),note节点的平衡因子为-2,说明删除后note的右子树导致note不平衡,则需要调整note的右子树(如果note右孩子节点的右子树高度大于左子树高度,进行RR调整,如果note右孩子节点的左子树高度大于有子树高度,进行RL调整)。

2、note的值>data,则应该在该节点的右子树寻找。在右子树中删除该节点成功后,需要调整平衡二叉树,以保持平衡。如果删除节点后(在右子树中删除节点,右子树高度不变或变矮),note节点的平衡因子为2,说明删除后note的左子树导致note不平衡,则需要调整note的左子树(如果note左孩子节点的右子树高度大于左子树高度,进行LR调整,如果note左孩子节点的左子树高度大于有子树高度,进行LL调整)。

3、note的值=data,找到!然后我们就可以进行删除了,但是平衡二叉树某节点的删除又分为以下4种情况:

1、该节点没有左、右孩子。直接删除该节点=NULL。

2、该节点只有左孩子。将其左孩子的值复制到该节点(仅移动值即可),直接删除其左孩子。

3、该节点只有右孩子。将其右孩子的值复制到该节点(仅移动值即可),直接删除其右孩子。

4、该节点既有左孩子又有右孩子,则分为以下两种情况:

    • 该节点左子树的高度大于右子树,找到该节点左孩子的最右节点right,将right的值复制到该节点,然后删除最右节点right。
    • 该节点右子树的高度大于左子树,找到该节点右孩子的最左节点left,将left的值复制到该节点,然后删除最左节点left。

最后,附上测试代码与结果:


bool AVLDelete(BSTNode *&T,int find)

{

	BSTNode *post,*pre;
	if (T==NULL)
	{
		return false;
	}
	else
		if(T->data == find)
		{			
			if (T->lchild==NULL && T->rchild==NULL)
			{
				T = NULL;
			}
			else
				if (T->lchild!=NULL && T->rchild == NULL)
				{
					T = T->lchild;
				}

				else

					if (T->rchild!=NULL && T->lchild == NULL)

					{
						T= T->rchild;
					}
					else
					{

						if (Height(T->lchild) > Height(T->rchild)

						{

							pre = T->lchild;

							while(pre->rchild)

							{

								pre = pre->rchild;

							}

							T->data = pre->data;

							AVLDelete((T->lchild),pre->data);

						}

						else

						{

							post = T->rchild;

							while(post->lchild)

							{

								post = post->lchild;

							}

							T->data = post->data;
							AVLDelet((T->rchild),post->data);

						}					
					}

					return true;

		}

		else
			
			if (find < T->data)

			{

				if (!AVLDelete(T->lchild,find))

				{

					return false;

				}

				else

				{
					T->height = Max(Height(T->lchild),Height(T->rchild))+1;

					if (Height(T->lchild)-Height(T->rchild)== -2)

					{

						if (Height(T->rchild->lchild) > Height(T->rchild->rchild))

						{

							modifiedRL(T);

						}

						else

						{

							modifiedRR(T);

						}					

					}				

				}

				return true;

			}else

			{

				if (!AVLDelete(T->rchild,find))

				{

					return false;

				}

				else

				{

					T->height = Max(Height(T->lchild),Height(T->rchild))+1;

					if (Height(T->lchild)-Height(T->rchild)== 2)

					{

						if (Height(T->lchild->lchild) > Height(T->lchild->rchild))

						{

							modifiedLL(T);

						}

						else

						{

							modifiedLR(T);

						}

					}

				}

				return true;

			}

			

			

			

}

下图片为测试结果(1-16个数字组成的平衡二叉树的先序、中序遍历结果,以及删除8节点后的先序、中序遍历结果。)

猜你喜欢

转载自blog.csdn.net/deeplan_1994/article/details/82421475