【数据结构】中的平衡搜索树-AVLTree

数据结构中:

AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树。

特点:

AVL树本质上还是一棵二叉搜索树,它的特点是:
1.本身首先是一棵二叉搜索树。
2.带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。
也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树)。

在AVL树里面,有几个重要的代码实现:
插入:
bool Insert(const K& key, const V& value)
	{
		if (_root == NULL)
		{
			_root = new Node(key, value);
			return true;
		}

		Node* parent = NULL;
		Node* cur = _root;

		//判断插入的值和cur的大小
		while (cur)
		{
			parent = cur;
			if (cur->_key < key)
			{
				cur = cur->_right;
			}
			else if (cur->_key>key)
			{
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}

		cur = new Node(key, value);//构建一个新的节点
		if (parent->_key > key)//如果父节点的值大于key,则key就为父节点的左边
		{
			parent->_left = cur;
			cur->_parent = parent;
		}
		else // 如果父节点的值小于key, 则key就为父节点的右边
		{
			parent->_right = cur;
			cur->_parent = parent;
		}

		while (parent)
		{
			if (cur == parent->_left)//如果插入的节点在parent的左边,则平衡因子-1
			{
				parent->_bf--;
			}
			else//如果插入的节点在parent的右边,则平衡因子+1
			{
				parent->_bf++;
			}

			if (parent->_bf == 0)//平衡因子为0,子树的高度没有变化
			{
				break;
			}
			else if(parent->_bf == -1 || parent->_bf == 1)
			{
				//子树的高度变化,但是高度没有变化,继续向上一层树进行检查,是否对上一层有影响
				cur = parent;
				parent = cur->_parent;
			}

			else//子树的高度为2或者-2 导致二叉树不再平衡,则需要进行旋转
			{
				if(parent->_bf==2)//说明右边子树的高度增加了
				{
					Node* subR = parent->_right;

					if (subR->_bf == 1)
					{
						RotateL(parent);
					}
					else
					{
						RotateRL(parent);
					}
				}

				else//说明左边的子树的高度增加了
				{
					Node* subL = parent->_left;
					if (subL->_bf == -1)
					{
						RotateR(parent);
					}
					else
					{
						RotateLR(parent);
					}
				}
				break;
			}
		}
	}
左单旋:
void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		parent->_right = subRL;
		if (subRL!=NULL)
		{
			subRL->_parent = parent;
		}
		subR->_left = parent;
		Node* ppNode = parent->_parent;
		parent->_parent = subR;
		if (ppNode == NULL)
		{
			subR = _root;
			subR->_parent = NULL;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = subR;
			}
			else
			{
				ppNode->_right = subR;
			}
			subR->_parent = ppNode;
		}
		parent->_bf = subR->_bf = 0;
	}
右单旋:
 
void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

		parent->_left = subLR;
		if (subLR)
		{
			subLR->_parent = parent;
		}
		subL->_right = parent;
		Node* ppNode = parent->_parent;
		parent->_parent = subL;

		if (ppNode == NULL)
		{
			_root = subL;
			subL->_parent = NULL;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = subL;
			}
			else
			{
				ppNode->_right = subL;
			}
			subL->_parent = ppNode;
		}
		parent->_bf = subL->_bf = 0;
	}
左右双旋:
 
void RotateLR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;
		int bf = subLR->_bf;

		RotateL(subL);
		RotateR(parent);

		if (bf == 0)
		{
			parent->_bf = subL->_bf = subLR->_bf = 0;
		}
		else if (bf==1)
		{
			subL->_bf = -1;
			parent->_bf = 0;
			subLR->_bf = 0;
		}
		else
		{
			subL->_bf = 0;
			subLR->_bf = 0;
			parent->_bf = 1;
		}
	}
右左双旋:
void RotateRL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		int bf = subRL->_bf;

		RotateR(subR);
		RotateL(parent);

		if (bf == 0)
		{
			parent->_bf = subR->_bf = subRL->_bf = 0;
		}
		else if (bf == -1)
		{
			parent->_bf = 0;
			subRL->_bf = 0;
			subR->_bf = 1;
		}
		else
		{
			parent->_bf = -1;
			subRL->_bf = 0;
			subR->_bf = 0;
		}
	}
判断是否是平衡树:
 
bool _IsBalance(Node* root,int height)
	{
		if (root == NULL)
		{
			height = 0;
			return true;
		}
		int l = 0;
		int r = 0;

		if (_IsBalance(root->_left, 1)&& _IsBalance(root->_right, r) && abs(r - 1) < 2)
		{
			height = l < r ? r + 1 : l + 1;

			if (root->_bf != r - 1)
			{
				cout << "平衡因子异常"<_key <
下面是完整的代码:
#include
using namespace std;

#include
template
struct AVLTreeNode
{
	AVLTreeNode* _left;
	AVLTreeNode* _right;
	AVLTreeNode* _parent;

	K _key;
	V _value; 
	int _bf;


	AVLTreeNode(const K& key, const V& value)
		:_left(NULL)
		, _right(NULL)
		, _parent(NULL)
		, _bf(0)
		, _key(key)
		, _value(value)
	{}
};


template
class AVLTree
{
	typedef AVLTreeNode Node;
public:
	AVLTree()
	:_root(NULL)
	{}

	~AVLTree()
	{}

	bool Insert(const K& key, const V& value)
	{
		if (_root == NULL)
		{
			_root = new Node(key, value);
			return true;
		}

		Node* parent = NULL;
		Node* cur = _root;

		//判断插入的值和cur的大小
		while (cur)
		{
			parent = cur;
			if (cur->_key < key)
			{
				cur = cur->_right;
			}
			else if (cur->_key>key)
			{
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}

		cur = new Node(key, value);//构建一个新的节点
		if (parent->_key > key)//如果父节点的值大于key,则key就为父节点的左边
		{
			parent->_left = cur;
			cur->_parent = parent;
		}
		else // 如果父节点的值小于key, 则key就为父节点的右边
		{
			parent->_right = cur;
			cur->_parent = parent;
		}

		while (parent)
		{
			if (cur == parent->_left)//如果插入的节点在parent的左边,则平衡因子-1
			{
				parent->_bf--;
			}
			else//如果插入的节点在parent的右边,则平衡因子+1
			{
				parent->_bf++;
			}

			if (parent->_bf == 0)//平衡因子为0,子树的高度没有变化
			{
				break;
			}
			else if(parent->_bf == -1 || parent->_bf == 1)
			{
				//子树的高度变化,但是高度没有变化,继续向上一层树进行检查,是否对上一层有影响
				cur = parent;
				parent = cur->_parent;
			}

			else//子树的高度为2或者-2 导致二叉树不再平衡,则需要进行旋转
			{
				if(parent->_bf==2)//说明右边子树的高度增加了
				{
					Node* subR = parent->_right;

					if (subR->_bf == 1)
					{
						RotateL(parent);
					}
					else
					{
						RotateRL(parent);
					}
				}

				else//说明左边的子树的高度增加了
				{
					Node* subL = parent->_left;
					if (subL->_bf == -1)
					{
						RotateR(parent);
					}
					else
					{
						RotateLR(parent);
					}
				}
				break;
			}
		}
	}

	void InOrder()
	{
		_InOrder(_root);
	}

	bool IsBalance()
	{
		int height = 0;
		return _IsBalance(_root,height);
	}
	
protected:
	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		parent->_right = subRL;
		if (subRL!=NULL)
		{
			subRL->_parent = parent;
		}
		subR->_left = parent;
		Node* ppNode = parent->_parent;
		parent->_parent = subR;
		if (ppNode == NULL)
		{
			subR = _root;
			subR->_parent = NULL;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = subR;
			}
			else
			{
				ppNode->_right = subR;
			}
			subR->_parent = ppNode;
		}
		parent->_bf = subR->_bf = 0;
	}

	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

		parent->_left = subLR;
		if (subLR)
		{
			subLR->_parent = parent;
		}
		subL->_right = parent;
		Node* ppNode = parent->_parent;
		parent->_parent = subL;

		if (ppNode == NULL)
		{
			_root = subL;
			subL->_parent = NULL;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = subL;
			}
			else
			{
				ppNode->_right = subL;
			}
			subL->_parent = ppNode;
		}
		parent->_bf = subL->_bf = 0;
	}

	
	void RotateLR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;
		int bf = subLR->_bf;

		RotateL(subL);
		RotateR(parent);

		if (bf == 0)
		{
			parent->_bf = subL->_bf = subLR->_bf = 0;
		}
		else if (bf==1)
		{
			subL->_bf = -1;
			parent->_bf = 0;
			subLR->_bf = 0;
		}
		else
		{
			subL->_bf = 0;
			subLR->_bf = 0;
			parent->_bf = 1;
		}
	}

	void RotateRL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		int bf = subRL->_bf;

		RotateR(subR);
		RotateL(parent);

		if (bf == 0)
		{
			parent->_bf = subR->_bf = subRL->_bf = 0;
		}
		else if (bf == -1)
		{
			parent->_bf = 0;
			subRL->_bf = 0;
			subR->_bf = 1;
		}
		else
		{
			parent->_bf = -1;
			subRL->_bf = 0;
			subR->_bf = 0;
		}
	}

	void _InOrder(Node* root)//中序
	{
		if (root == NULL)
		{
			return;
		}
		_InOrder(root->_left);
		cout << root->_key << ":" << root->_value << endl;
		_InOrder(root->_right);
	}

	size_t _Height(Node* root)
	{
		if (root == NULL)
		{
			return 0;
		}
		size_t LHeight = _Height(root->_left);
		size_t RHeight = _Height(root->_right);

		return LHeight < RHeight ? RHeight + 1 : LHeight + 1;
	}

	bool _IsBalance(Node* root,int height)
	{
		if (root == NULL)
		{
			height = 0;
			return true;
		}
		int l = 0;
		int r = 0;

		if (_IsBalance(root->_left, 1)&& _IsBalance(root->_right, r) && abs(r - 1) < 2)
		{
			height = l < r ? r + 1 : l + 1;

			if (root->_bf != r - 1)
			{
				cout << "平衡因子异常"<_key < tree;

	for (int i = 0; i < 9; i++)
	{
		tree.Insert(a[i], i);
	}
	tree.InOrder();
	tree.IsBalance();
}


int main()
{
	Test();
	system("pause");
	return 0;
}


 


你可能感兴趣的:(数据结构)