1. 程式人生 > >AVL樹-平衡二叉樹

AVL樹-平衡二叉樹

平衡二叉樹是高度平衡的二叉樹:

1 左右子樹的高度差最多為1.

2 主要的實現地方是插入平衡和刪除平衡。

3 為了實現平衡,每個節點儲存了一個高度h成員。

4 當插入和刪除破壞了平衡的時候需要進行旋轉;

5 根據左右子樹高度差的不同進行四中不同的旋轉:左左、右右、左右、右左

百度雲下載sln檔案:https://pan.baidu.com/s/1pxPGQDYhbcG-E6sE26WfuA

下面是插入和刪除的核心程式碼:

插入:

//Insert
void CAVLTree::InsertPri(CTreeNode*& _pNode, CTreeNode*& _pParentNode, const int _key, const CEntry& _entry)
{
	if (_pNode == nullptr)//如果節點為空,就在此節點處加入_entry資訊
	{
		//Counter::AddCount(CounterType::AVLInsert);

		_pNode = new CTreeNode();
		_pNode->key = _key;
		_pNode->value = _entry;
		_pNode->parent = _pParentNode;

		CTreeNode::UpdateParentHeight(_pNode);

		return;
	}
	
	if (_pNode->value < _entry)
	{
		//Counter::AddCount(CounterType::AVLInsert);

		InsertPri(_pNode->rchild, _pNode, _key, _entry);
		int rHight = CTreeNode::GetHeight(_pNode->rchild);
		int lHight = CTreeNode::GetHeight(_pNode->lchild);
		int height = std::max(lHight, rHight) - std::min(lHight, rHight);
		if (2 == height)
		{
			if (_entry >= _pNode->rchild->value)//儘量使用單旋轉==
			{
				RightRightRotate(_pNode);
			}
			else
			{
				DoubleRotateRL(_pNode);
			}
		}
	}
	else if (_entry < _pNode->value)//如果_entry小於節點的值,就繼續在節點的左子樹中插入_entry
	{
		//Counter::AddCount(CounterType::AVLInsert);

		InsertPri(_pNode->lchild, _pNode, _key, _entry);
		int rHight = CTreeNode::GetHeight(_pNode->rchild);
		int lHight = CTreeNode::GetHeight(_pNode->lchild);
		int height = std::max(lHight, rHight) - std::min(lHight, rHight);
		if (2 == height)
		{
			if (_entry <= _pNode->lchild->value)//儘量使用單旋轉==
			{
				LeftLeftRotate(_pNode);
			}
			else
			{
				DoubleRotateLR(_pNode);
			}
		}
	}
}

刪除:

void CAVLTree::DeletePri(CTreeNode* &_pNode, const CEntry& _entry)
{
	if (_pNode == nullptr)
	{
		return;
	}
	if (_entry < _pNode->value)
	{
		DeletePri(_pNode->lchild, _entry);
		int rHight = CTreeNode::GetHeight(_pNode->rchild);
		int lHight = CTreeNode::GetHeight(_pNode->lchild);
		int height = std::max(lHight, rHight) - std::min(lHight, rHight);
		if (2 == height)
		{
			if (_pNode->rchild->lchild != nullptr && _pNode->rchild->lchild->height > _pNode->rchild->rchild->height)
			{
				DoubleRotateRL(_pNode);
			}
			else
			{
				RightRightRotate(_pNode);
			}
		}
	}
	else if (_entry > _pNode->value)
	{
		DeletePri(_pNode->rchild, _entry);
		int rHight = CTreeNode::GetHeight(_pNode->rchild);
		int lHight = CTreeNode::GetHeight(_pNode->lchild);
		int height = std::max(lHight, rHight) - std::min(lHight, rHight);
		if (2 == height)
		{
			if (_pNode->lchild->rchild != nullptr && (_pNode->lchild->rchild->height > _pNode->lchild->lchild->height))
			{
				DoubleRotateLR(_pNode);
			}
			else
			{
				LeftLeftRotate(_pNode);
			}
		}
	}
	else
	{
		if (_pNode->lchild&&_pNode->rchild)//this node has two childs
		{
			CTreeNode* temp = _pNode->rchild;

			while (temp->lchild != nullptr)
			{
				temp = temp->lchild;//find min in rchild
			}

			_pNode->value = temp->value;
			
			DeletePri(_pNode->rchild, temp->value);
			int rHight = CTreeNode::GetHeight(_pNode->rchild);
			int lHight = CTreeNode::GetHeight(_pNode->lchild);
			int height = std::max(lHight, rHight) - std::min(lHight, rHight);
			if (2 == height)
			{
				if (_pNode->lchild->rchild != nullptr && (_pNode->lchild->rchild->height > _pNode->lchild->lchild->height))
				{
					DoubleRotateLR(_pNode);
				}
				else
				{
					LeftLeftRotate(_pNode);
				}
			}
		}
		else//this node has 1 or 0 child
		{
			CTreeNode* temp = _pNode;
			if (_pNode->lchild == nullptr)
			{
				_pNode = _pNode->rchild;
			}
			else if (_pNode->rchild == nullptr)
			{
				_pNode = _pNode->lchild;
			}
			delete(temp);
			temp = nullptr;
		}
	}
	if (_pNode == nullptr)
	{
		return;
	}
	
	return;
}

輸出: