您的位置:首页 > 其它

AVL树 四种旋转的场景

2017-05-24 12:12 190 查看
以下图的平衡因子统一为左子树高度减去右子树高度。

1 左单旋 (右右 - 在较高右子树的右侧插入节点)

   


附上:单个节点声明的代码

struct AVLTreeNode
{
AVLTreeNode(const K& key, const V& value)
: _pLeft(NULL)
, _pRight(NULL)
, _pParent(NULL)
, _key(key)
, _value(value)
, _bf(0)
{}

AVLTreeNode<K, V> *_pLeft;
AVLTreeNode<K, V> *_pRight;
AVLTreeNode<K, V> *_pParent;
K _key;
V _value;
int _bf; // 平衡因子:right-left
};
附上 - 左单旋代码:

void _RotateL(Node* pParent)
{
if (pParent)
{
Node *pPParent = pParent->_pParent;
Node * pSubR = pParent->_pRight;
Node * pSubRL = pParent->_pLeft;
if (pSubRL)
{
pSubRL->_pParent = pParent;
}
pParent->_pRight = pSubRL;
pSubR->_pLeft = pParent;
pParent->_pParent = pSubR;
pSubR->_pParent = pPParent;
if (pPParent == NULL)
{
_pRoot = pSubR;
}
else
{
if (pPParent->_pLeft == pParent) pPParent->_pLeft = pSubR;
else
pPParent->_pRight = pSubR;
}
pSubR->_bf = 0;
pParent->_bf = 0;
}
}

2 右单旋 (左左-在较高左子树中的左侧插入节点)



附上 -右单旋代码:

void _RotateR(Node* pParent)
{
if (pParent)
{
Node*pPParent = pParent->_pParent;
Node*pSubL = pParent->_pLeft;
Node*pSubLR = pSubL->_pRight;
if (pSubLR)
{
pSubLR->_pParent = pParent;
}
pParent->_pLeft = pSubLR;
pParent->_pParent = pSubL;
pSubL->_pRight = pParent;
pSubL->_pParent = pPParent;
if (pPParent==NULL)
{
_pRoot = pSubL;
}
else
{
if (pParent->_pRight == pParent)pParent->_pRight = pSubL;
else
pParent->_pLeft = pSubL;
}
pSubL->_bf = 0;
pParent->_bf = 0;

}
}

3 右左双旋(右左-在较高右子树的左侧插入)





附上代码 - 右左双旋:

void _RotateRL(Node* pParent)
{
Node *PsubR = pParent->_pRight;
Node* pSubRL = PsubR->_pLeft;
int bf = pSubRL->_bf;
_RotateR(pParent->_pRight);
_Rotate(pParent);
if (bf == -1) pParent->_bf = 1;
else PsubR->_bf = -1;
}

4 左右双旋(左右-在较高左子树的右侧插入)


   

   


void _RotateLR(Node* pParent)
{
Node * PsubL = pParent->_pLeft;
Node * psubLR = PsubL->_pRight;
int bf = psubLR->_bf;
_RotateL(pParent->_pLeft);
_RotateR(pParent);
if (bf == 1) pParent->_bf = -1;
else PsubL->_bf = 1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: