AVL学习笔记

时间:2022-05-14 07:22:01

AVL,平衡二叉查找树。删除,插入,查找的复杂度都是O(logn)。它是一棵二叉树。对于每个节点来说,它的左孩子的键值都小于它,右孩子的键值都大于它。对于任意一个节点,它的左右孩子的高度差不大于1。树的高度的定义为:空节点的高度为0,非空节点的高度为左右孩子高度的最大值加1。

在插入删除过程中,会出现不平衡的时候。这时,会通过以下方式进行旋转保持树的平衡。下图中每一列最后一行是旋转后的结果,上面两行是对应的初始化状态。

AVL学习笔记

1 插入。在以某个节点为根的子树中插入一个节点后,有可能使得该节点的左右子树的高度差大于1(其实此时的高度差是2),那么视情况进行LL,RR,LR,RL四种旋转中的一种可维持树的平衡。

2 删除。删除的键值小于当前节点键值时,在左子树中删除;大于当前节点键值时在右子树中进行删除;否则就是删除当前节点。删除当前节点时,找到后继节点,然后将后继结点替换当前节点,然后递归地删除这个后继结点即可。

template<class _ValyeType,class _FuncType>
class CAVLTree
{
protected:
struct AVLTreeNode
{
_ValyeType m_iValue;
AVLTreeNode* m_pLeftSon;
AVLTreeNode* m_pRightSon;
int m_nHeight;
int m_nValueNumber;
};
AVLTreeNode* m_pRoot;
_FuncType* m_pCompareFunc; AVLTreeNode* _NewNode()
{
AVLTreeNode* pNode=new AVLTreeNode;
pNode->m_pLeftSon=nullptr;
pNode->m_pRightSon=nullptr;
pNode->m_nHeight=;
pNode->m_nValueNumber=;
return pNode;
}
AVLTreeNode* _NewNode(const _ValyeType& iValue)
{
AVLTreeNode* pNode=new AVLTreeNode;
pNode->m_pLeftSon=nullptr;
pNode->m_pRightSon=nullptr;
pNode->m_nHeight=;
pNode->m_iValue=iValue;
pNode->m_nValueNumber=;
return pNode;
} int _Height(AVLTreeNode* pNode)
{
if(pNode) return pNode->m_nHeight;
return ;
} void _PushUp(AVLTreeNode* pNode)
{
if(!pNode) return;
const int nLeftSonHeight=_Height(pNode->m_pLeftSon);
const int nRightSonHeight=_Height(pNode->m_pRightSon);
if(nLeftSonHeight<nRightSonHeight) pNode->m_nHeight=+nRightSonHeight;
else pNode->m_nHeight=+nLeftSonHeight;
} /**
pNode的左孩子将成为根,返回新的树根
**/
AVLTreeNode* _LLRotate(AVLTreeNode* pNode)
{
if(!pNode) return pNode;
AVLTreeNode* pLeftSon=pNode->m_pLeftSon;
pNode->m_pLeftSon=pLeftSon->m_pRightSon;
pLeftSon->m_pRightSon=pNode;
_PushUp(pNode);
_PushUp(pLeftSon);
return pLeftSon;
} /**
pNode的右孩子将成为根,返回新的树根
**/
AVLTreeNode* _RRRotate(AVLTreeNode* pNode)
{
if(!pNode) return pNode;
AVLTreeNode* pRightSon=pNode->m_pRightSon;
pNode->m_pRightSon=pRightSon->m_pLeftSon;
pRightSon->m_pLeftSon=pNode;
_PushUp(pNode);
_PushUp(pRightSon);
return pRightSon;
}
/**
pNode的左孩子的右孩子将成为根,返回新的树根
**/
AVLTreeNode* _LRRotate(AVLTreeNode* pNode)
{
if(!pNode) return pNode;
pNode->m_pLeftSon=_RRRotate(pNode->m_pLeftSon);
return _LLRotate(pNode);
} /**
pNode的右孩子的左孩子将成为根,返回新的树根
**/
AVLTreeNode* _RLRotate(AVLTreeNode* pNode)
{
if(!pNode) return pNode;
pNode->m_pRightSon=_LLRotate(pNode->m_pRightSon);
return _RRRotate(pNode);
} AVLTreeNode* _Rotate(AVLTreeNode* pNode)
{
if(!pNode) return pNode;
if(==_Height(pNode->m_pLeftSon)-_Height(pNode->m_pRightSon))
{
if(_Height(pNode->m_pLeftSon->m_pLeftSon)>=_Height(pNode->m_pLeftSon->m_pRightSon))
{
pNode=_LLRotate(pNode);
}
else pNode=_LRRotate(pNode);
}
else if(==_Height(pNode->m_pRightSon)-_Height(pNode->m_pLeftSon))
{
if(_Height(pNode->m_pRightSon->m_pLeftSon)>=_Height(pNode->m_pRightSon->m_pRightSon))
{
pNode=_RLRotate(pNode);
}
else pNode=_RRRotate(pNode);
}
return pNode;
} AVLTreeNode* _Insert(AVLTreeNode* pRoot,const _ValyeType& iInsertValue)
{
if(nullptr==pRoot)
{
pRoot=_NewNode(iInsertValue); return pRoot;
}
else if(m_pCompareFunc(iInsertValue,pRoot->m_iValue))
{
pRoot->m_pLeftSon=_Insert(pRoot->m_pLeftSon,iInsertValue);
if(==_Height(pRoot->m_pLeftSon)-_Height(pRoot->m_pRightSon))
{
if(m_pCompareFunc(iInsertValue,pRoot->m_pLeftSon->m_iValue))
{
pRoot=_LLRotate(pRoot);
}
else
{
pRoot=_LRRotate(pRoot);
}
}
}
else if(m_pCompareFunc(pRoot->m_iValue,iInsertValue))
{
pRoot->m_pRightSon=_Insert(pRoot->m_pRightSon,iInsertValue);
if(==_Height(pRoot->m_pRightSon)-_Height(pRoot->m_pLeftSon))
{
if(m_pCompareFunc(iInsertValue,pRoot->m_pRightSon->m_iValue))
{
pRoot=_RLRotate(pRoot);
}
else
{
pRoot=_RRRotate(pRoot);
}
}
}
else
{
++pRoot->m_nValueNumber;
} _PushUp(pRoot);
return pRoot;
} AVLTreeNode* _Delete(AVLTreeNode* pRoot,const _ValyeType& iDeleteValue)
{
if(nullptr==pRoot) return nullptr;
if(m_pCompareFunc(iDeleteValue,pRoot->m_iValue))
{
pRoot->m_pLeftSon=_Delete(pRoot->m_pLeftSon,iDeleteValue);
}
else if(m_pCompareFunc(pRoot->m_iValue,iDeleteValue))
{
pRoot->m_pRightSon=_Delete(pRoot->m_pRightSon,iDeleteValue);
}
else
{
if(==--pRoot->m_nValueNumber)
{
if(nullptr==pRoot->m_pLeftSon)
{
AVLTreeNode* pTmp=pRoot;
pRoot=pRoot->m_pRightSon;
delete pTmp;
}
else if(nullptr==pRoot->m_pRightSon)
{
AVLTreeNode* pTmp=pRoot;
pRoot=pRoot->m_pLeftSon;
delete pTmp;
}
else
{
AVLTreeNode* pTmp=pRoot->m_pRightSon;
while(pTmp->m_pLeftSon) pTmp=pTmp->m_pLeftSon;
pRoot->m_iValue=pTmp->m_iValue;
pRoot->m_pRightSon=_Delete(pRoot->m_pRightSon,pRoot->m_iValue);
}
}
else
{
return pRoot;
}
}
_PushUp(pRoot);
if(pRoot&&pRoot->m_pLeftSon) pRoot->m_pLeftSon=_Rotate(pRoot->m_pLeftSon);
if(pRoot&&pRoot->m_pRightSon) pRoot->m_pRightSon=_Rotate(pRoot->m_pRightSon);
if(pRoot) pRoot=_Rotate(pRoot);
return pRoot;
} public:
CAVLTree(_FuncType* pCompareFunc):m_pRoot(nullptr),m_pCompareFunc(pCompareFunc) {} void Insert(const _ValyeType& iInsertValue)
{
m_pRoot=_Insert(m_pRoot,iInsertValue);
} void Delete(const _ValyeType& iDeleteValue)
{
m_pRoot=_Delete(m_pRoot,iDeleteValue);
} int Find(const _ValyeType& iSearchValue)
{
AVLTreeNode* pCurrent=m_pRoot;
while()
{
if(!pCurrent) break;
if(m_pCompareFunc(iSearchValue,pCurrent->m_iValue))
{
pCurrent=pCurrent->m_pLeftSon;
}
else if(m_pCompareFunc(pCurrent->m_iValue,iSearchValue))
{
pCurrent=pCurrent->m_pRightSon;
}
else return pCurrent->m_nValueNumber;
}
return ;
} };