標籤:struct 大於 最大值 分享 break number alt 狀態 val
AVL,平衡二叉尋找樹。刪除,插入,尋找的複雜度都是O(logn)。它是一棵二叉樹。對於每個節點來說,它的左孩子的索引值都小於它,右孩子的索引值都大於它。對於任意一個節點,它的左右孩子的高度差不大於1。樹的高度的定義為:空節點的高度為0,非空節點的高度為左右孩子高度的最大值加1。
在插入刪除過程中,會出現不平衡的時候。這時,會通過以下方式進行旋轉保持樹的平衡。中每一列最後一行是旋轉後的結果,上面兩行是對應的初始化狀態。
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=1; pNode->m_nValueNumber=0; return pNode; } AVLTreeNode* _NewNode(const _ValyeType& iValue) { AVLTreeNode* pNode=new AVLTreeNode; pNode->m_pLeftSon=nullptr; pNode->m_pRightSon=nullptr; pNode->m_nHeight=1; pNode->m_iValue=iValue; pNode->m_nValueNumber=1; return pNode; } int _Height(AVLTreeNode* pNode) { if(pNode) return pNode->m_nHeight; return 0; } 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=1+nRightSonHeight; else pNode->m_nHeight=1+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(2==_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(2==_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(2==_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(2==_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(0==--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(1) { 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 0; }};
AVL學習筆記