一.AVL树的旋转
AVL树是平衡搜索二叉树的一种。
平衡因子:节点右树的高度减左树的高度,AVL树规定平衡因子的绝对值小于2。若不在这个范围内,说明该树不平衡。
AVL树节点:
struct AVLTreeNode
{
	AVLTreeNode(const T& data = T())
		: _pLeft(nullptr)
		, _pRight(nullptr)
		, _pParent(nullptr)
		, _data(data)
		, _bf(0)
	{}
	AVLTreeNode<T>* _pLeft;
	AVLTreeNode<T>* _pRight;
	AVLTreeNode<T>* _pParent;
	T _data;
	int _bf;   // 节点的平衡因子
};如果在一棵原本是平衡的AVL树中插入一个新节点,可能造成不平衡,此时必须调整树的结构, 使之平衡化。根据节点插入位置的不同,AVL树的旋转分为四种:
1. 新节点插入较高左子树的左侧---左左:右单旋

void RotateL(Node* pParent)
	{
		Node* SubR = pParent->_pRight; 
		Node* SubRL = SubR->_pLeft;
		
		pParent->_pRight = SubRL;
		if (SubRL)
			SubRL->_pParent = pParent;
		SubR->_pLeft = pParent;
		pParent->_pParent = SubR;
		if (pParent->_pParent == nullptr)
		{
			_pRoot = SubR;
			SubR->_pParent = nullptr;
		}
		else
		{
			if (pParent->_pParent->_pLeft == pParent)
			{
				pParent->_pParent->_pLeft = SubR;
			}
			else
			{
				pParent->_pParent->_pRight = SubR;
			}
		}
		SubR->_bf = SubRL->_bf = 0;
	}2. 新节点插入较高右子树的右侧---右右:左单旋

void RotateR(Node* pParent)
	{
		Node* SubL = pParent->_pLeft;
		Node* SubLR = SubL->_pRight;
		pParent->_pLeft = SubLR;
		if(SubLR)
		SubLR->_pParent = pParent;
		SubL->_pRight = pParent;
		pParent->_pParent = SubL;
		
		if (pParent->_pParent == nullptr)
		{
			_pRoot = SubL;
			SubL->_pParent = nullptr;
		}
		else
		{
			if (pParent == pParent->_pParent->_pRight)
			{
				pParent->_pParent->_pRight = SubL;
			}
			else
			{
				pParent->_pParent->_pLeft = SubL;
			}
			SubL->_pParent = pParent->_pParent;
		}
		SubL->_bf = SubLR->_bf = 0;
	}3. 新节点插入较高左子树的右侧---左右:先左单旋再右单旋

void RotateLR(Node* pParent)
	{
		Node* SubL = pParent->_pLeft;
		Node* SubLR = SubL->_pRight;
		RotateL(SubL);
		RotateR(pParent);
		if (SubLR->_bf == -1)
		{
			SubL->_bf = 0;
			SubLR->_bf = 0;
			pParent->_bf = 1;
		}
		else if (SubLR->_bf == 1)
		{
			SubL->_bf = -1;
			SubLR->_bf = 0;
			pParent->_bf = 0;
		}
		else
		{
			assert(false);
		}
	}4. 新节点插入较高右子树的左侧---右左:先右单旋再左单旋

void RotateRL(Node* pParent)
	{
		Node* SubR = pParent->_pRight;
		Node* SubRL = SubR->_pLeft;
		RotateR(SubR);
		RotateL(pParent);
		if (SubRL->_bf == 1)
		{
			SubR->_bf = 0;
			pParent->_bf = -1;
			SubRL = 0;
		}
		else if(SubRL->_bf == 0)
		{
			SubR->_bf = 0;
			pParent->_bf = 0;
			SubRL = 0;
		}
		else if (SubRL->_bf == -1)
		{
			SubR->_bf = 1;
			pParent->_bf = 0;
			SubRL = 0;
		}
		else
		{
			assert(false);
		}
	}二.AVL树的插入
插入一个节点后平衡因子可能会改变。所以不仅要改变指针方向,还要更新平衡因子的值。
bool Insert(const T& data)
	{
		if (_pRoot == nullptr)
		{
			_pRoot = new Node(data);
			return true;
		}
		Node* cur = _pRoot;
		Node* parent = _pRoot;
		while (cur)
		{
			if (data < cur->_data)
			{
				parent = cur;
				cur = cur->_pLeft;
			}
			else if (data < cur->_data)
			{
				parent = cur;
				cur = cur->_pRight;
			}
			else
			{
				return false;
			}
		}
		cur = new Node(data);
		if (data < parent->_data)
		{
			parent->_pLeft = cur;
		}
		else
		{
			parent->_pRight = cur;
		}
		//更新平衡因子
		while (parent)
		{
			if (parent->_pLeft = cur)
			{
				parent->_bf-- ;
			}
			else
			{
				parent->_bf++;
			}
			if (parent->_bf == 1 || parent->_bf == -1)
			{
				cur = parent;
				parent = parent->_pParent;
			}
			else if (parent->_bf == 2 || parent->_bf == -2)
			{
				if (parent->_bf == 2 && cur->_bf == 1)
				{
					RotateR(parent);
				}
				else if (parent->_bf == -2 && cur->_bf == -1)
				{
					RotateL(parent);
				}
				else if (parent->_bf == 2 && cur->_bf == -1)
				{
					RotateRL(parent);
				}
				else
				{
					RotateLR(parent);
				}
			}
			else
			{
				assert(false);
			}
		}
		return true;
	}三.AVL树的验证
1.求树的高度
size_t _Height(Node* pRoot)
	{
		if (pRoot == nullptr)
		{
			return 0;
		}
		int LestTreeHeight = _Height(pRoot->_pLeft);
		int RightTreeHeight = _Height(pRoot->_pRight);
		return LestTreeHeight > RightTreeHeight ? LestTreeHeight + 1 : RightTreeHeight + 1;
	}2.验证是否为平衡二叉树
bool _IsAVLTree(Node* pRoot)
	{
		if (pRoot == nullptr)
		{
			return true;
		}
		int LestTreeHeight = _Height(pRoot->_pLeft);
		int RightTreeHeight = _Height(pRoot->_pRight);
		int diff = RightTreeHeight - LestTreeHeight;
		if (abs(diff) >= 2 || abs(diff) != pRoot->_bf)
		{
			return false;
		}
		return _IsAVLTree(pRoot->_pLeft) && _IsAVLTree(pRoot->_pRight);
	}3.测试用例验证
int main()
{
	int arr[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16,14 };
	AVLTree<int> a;
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]);i++)
	{
		a.Insert(i);
	}
	cout << a.IsAVLTree() << endl;
	return 0;
}



















