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;
}
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;
}
相关文章推荐
- AVL树的插入与删除,重点是四种旋转
- AVL树的插入以及四种旋转
- AVL树的插入以及四种旋转解析
- AVL树的四种旋转--初步解析
- C++实现AVL树(四种旋转详解)
- Java的四种引用,强弱软虚,用到的场景
- 消息队列使用的四种场景介绍
- AVL树的旋转操作详解
- krpano 教程 - 自动旋转和自动场景跳转的实现
- AVL树的旋转,插入,删除操作
- AVL树的旋转
- three.js旋转的场景canvas_camera_orthographic
- AVL树的旋转实现
- 消息队列使用的四种场景介绍
- [数据结构与算法]AVL树的旋转
- Android:图解四种启动模式 及 实际应用场景解说
- AVL树之旋转
- 消息队列使用的四种场景介绍
- AVL树的旋转
- Activity四种启动模式的利用场景