【数据结构】平衡二叉树[AVL树](二)——删除

前面介绍了平衡二叉树的插入操作:平衡二叉树的插入,这里来介绍平衡二叉树的删除,平衡二叉树是一棵带有平衡条件的二叉查找树,其删除操作是在二叉查找树的基础上添加平衡调整算法。

二叉查找树的删除操作参见博文:二叉查找树的删除(第七点)

先看一下示意图()

《【数据结构】平衡二叉树[AVL树](二)——删除》

/*二叉查找树的性质让我们可以很方便的查找最小最大键值*/
/*查找最小键值节点:直接递归遍历左子树叶子节点*/
AvlNode* AvlTree::findMin(AvlNode *node)
{
	if (NULL == node)
		return NULL;

	else if (NULL == node->leftchild)
		return node;

	else
		return findMin(node->leftchild);
}

/*非递归实现查找最大键值节点*/
AvlNode* AvlTree::findMax(AvlNode *node)
{
	if (node != NULL)
	{
		while (node->rightchild)
			node = node->rightchild;
	}

	return node;
}

void AvlTree::Delete(int val)
{
	if(NULL == Root)
		return;
	else
		Delete(Root, val);
}

//节点的删除就是不断的交换数据,更改删除节点,最后定位到叶子节点
//
void AvlTree::Delete(AvlNode *&node, int val)
{
	AvlNode *tempnode = NULL;
	if(NULL == node)
		return;

	else if(val < node->data)
		Delete(node->leftchild, val);
	else if(val > node->data)
		Delete(node->rightchild, val);

	//find the val
	else if(node->leftchild && node->rightchild)
	{
		tempnode = findMin(node->rightchild);
		node->data = tempnode->data;
		Delete(node->rightchild, node->data);   //理解!待删除节点键值变换
	}                                           //此后要删除的键值节点不是val
	else
	{
		if(node->leftchild && (NULL == node->rightchild))
		{
			tempnode = findMax(node->leftchild);
			node->data = tempnode->data;
			Delete(node->leftchild, node->data);
		}
		else if (node->rightchild && (NULL == node->leftchild))
		{
			tempnode = findMin(node->rightchild);
			node->data = tempnode->data;
			Delete(node->rightchild, node->data);
		}
		else
		{
			delete(node);
			node = NULL;
		}
	}

	if (node)   //必须添加这个条件,利用递归的力量,调整平衡
	{  
		//平衡判断
		if (2 == Height(node->leftchild) - Height(node->rightchild))
		{
			//情况判断
			if (Height(node->leftchild->leftchild) >= Height(node->leftchild->rightchild))
				RotationLeftOnce(node);
			else
			{
				RotationRightOnce(node->leftchild);
				RotationLeftOnce(node);
			}
		}

		if (2 == Height(node->rightchild) - Height(node->leftchild))
		{
			if (Height(node->rightchild->rightchild) >= Height(node->rightchild->leftchild))
				RotationRightOnce(node);
			else
			{
				RotationLeftOnce(node->rightchild);
				RotationRightOnce(node);
			}
		}
	}
}

上面的删除操作具体参见:二叉查找树的删除,另外平衡二叉树的查找,遍历与二叉查找树一样。

二、清空二叉树(析构函数)

void AvlTree::MakeEmpty(AvlNode *&node)
{
	if (node)
	{
		MakeEmpty(node->leftchild);
		MakeEmpty(node->rightchild);
		delete node;
	}
	node = NULL;
}

三、平衡二叉树时间复杂度分析

平衡二叉树在二叉查找树的基础上添加了旋转算法,但是旋转操作仅仅改变少数指针的指向,耗费常数时间,平衡二叉树加入了平衡机制,所以其深度为logN,查找、插入和删除在平均和最坏情况下都是O(logN)。对比二叉查找树,时间上稳定了很多。

    原文作者:平衡二叉树
    原文地址: https://blog.csdn.net/wenqian1991/article/details/22291675
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞