思路:
{
Node* subR = parent->_right;
Node* subRL = subR->_left;//先定义两节点
parent->_right = subRL;//parent的右指向subRL
if (subRL)//subRL可能不会存在,也可能存在
{
subRL->_parent = parent;
}
subR->_left = parent;//subR的左指向parent
subR->_parent = parent ->_parent;//subR的父亲就是parent的父亲了
Node* ppNode = parent->_parent;//定义ppNode节点为parent的父亲节点
parent->_parent = subR;//parent的父亲节点也就是subR
if (ppNode == NULL)//如果ppNode为空,
{
_root = subR;
subR->_parent = NULL;
}
else if (ppNode->_left == parent)
{
ppNode->_left = subR;
}
else
{
ppNode->_right = subR;
}
subR->_parent = ppNode;
parent->_bf = subR->_bf = 0;//更新平衡因子
}
----------------------------------------------------------------------------------------------------------------------------------
思路:
void RotateR(Node* parent)//右单旋
{
Node* subL = parent->_left;//定义两个节点subL,subLR
Node* subLR = subL->_right;
parent->_left = subLR;//parent的左指向subLR
if (subLR)
{
subLR->_parent = parent;
}
subL->_right = parent;//subL的右指向parent
subL->_parent = parent->_parent;//subL的父亲就是parent的父亲
Node* ppNode = parent->_parent;//定义一个节点ppNode为parent的父亲节点
if (ppNode == NULL)
{
root = subL;
subL->_parent = NULL;
}
else if (ppNode->_left==parent)
{
ppNode->_left = subL;
}
else
{
ppNode->_right = subL;
}
subL->_parent = ppNode;
subL->_bf = parent->_bf = 0;
}
----------------------------------------------------------------------------------------------------------------------------------
思路:
{
Node* subL = parent->_left;//定义节点subL,subLR
Node* subLR = subL->_right;
int bf = subLR->_bf;//定义平衡因子,初始化为subLR的平衡因子
RotateL(parent->_left);//以parent的左为轴进行左单旋
RotateR(parent);//以parent为轴进行右单旋
//画完图一目了然
if (subLR->_bf == 1)//如果subLR的平衡因子为1,则subL和parent的平衡因子如下
{
subL->_bf = -1;
parent->_bf = 0;
}
else if (subLR->_bf == -1)//同上
{
subL->_bf = 0;
parent->_bf = 1;
}
else//subLR的平衡因子为0
{
subL->_bf = parent->_bf = 0;
}
subLR->_bf = 0;//最终将subLR的平衡因子置为0
}
----------------------------------------------------------------------------------------------------------------------------------
思路:
{
Node* subR = parnet->_right;
Node* subRL = subR->_left;
int bf = subRL->_bf;
RotateR(parent->_right);
RotateL(parent);
if (subRL->_bf == 1)
{
subR->_bf = 0;
parent->_bf = -1;
}
else if (subRL->_bf == -1)
{
subR->_bf = 1;
parent->_bf = 0;
}
else
{
subR->_bf = parent->_bf = 0;
}
subRL->_bf = 0;
}
----------------------------------------------------------------------------------------------------------------------------------
Insert:
bool Insert(const K& key, const V& value)//插入
{
//1、AVL树位空树,直接插入为根节点
//2、插入值与根节点相同,返回false
//3、插入值小于根节点,递归到左子树,反之递归到右子树
if (_root == NULL)
{
_root = new Node(key, value);
return true;
}
Node* parent = NULL;
Node* cur = _root;//根节点给cur,根节点的父亲即为空
while (cur)//向下递归保证cur一直存在,直到cur为空说明已经递归到叶子节点了
{
if (cur->_key > key)//左递归
{
parent = cur;
cur = parent->_left;
}
else if (cur->_key < key)//右递归
{
parent = cur;
cur = parent->_right;
}
else//插入节点等于根节点
{
return false;
}
}
//到这里就找到key的父亲了,接下来判断key应该是其父亲的左孩子还是右孩子
cur = new Node(key, value);//
if (key > parent->_key)
{
parent->_right = cur;
cur->_parent = parent;
}
else if (key < parent->_key)
{
parent->_left = cur;
cur->_parent = parnet;
}
//到这里就找到key的插入点了,接下来判断平衡因子是否正确
//平衡因子有3种:0、正负1、正负2
//第一种情况:如果parent目前的_bf是0,说明之前parent的_bf是正负1,插入新节点后变为0了
//第二种情况:如果parent目前的_bf是正负1,说明之前parent的_bf是0,插入新节点后不仅会
//影响parent的_bf,而且会影响parent的parent的_bf,所以要向上回溯,直到所有的parent的_bf=0
//或者parent的_bf是正负2停止
//第三种情况:遇到parent的_bf是正负2,就需要旋转,旋转又分为左单旋、右单旋、左右双旋、右左双旋
while (parent)//这里找到了Parent,就以parent为条件
{
if (parent->_left = cur)//说明新插入节点插到了父亲的左孩子位置,那么父亲的
{ //平衡因子需要减1
parent->_bf--;
}
else
{
parent->_bf++;//新插入节点插到了父亲的右孩子位置,父亲的bf要加1
}
if (parent->_bf == 0)//父亲的bf为0,不影响其他
{
break;
}
else if (parent->_bf == 1 || parent->_bf == -1)//回溯
{
cur = parent;
parent = cur->_parent;
}
else if (parent->_bf == 2 || parent->_bf == -2)//平衡因子大于绝对值1,需要旋转
//接下来判断是哪一种旋转
{
}
}
}
----------------------------------------------------------------------------------------------------------------------------------
{
if (root == NULL)
return;
InOrder(root->_left);
cout << root->_key << " ";//该句必须放中间,保证“左根右”
InOrder(root->_right);
}
bool IsBalance()//是否为平衡树
{
if (root == NULL)//如果根为空,该树满足是平衡树
return true;
int bf = Height(root->_right) - Height(root->_left);//定义bf为平衡因子,右子树高度减去左子树高度
if (abs(bf) > 1 || bf != root->_bf)//如果bf的绝对值大于1,或者bf不等于根节点的bf,那么就输出平衡因子有误的节点位置
{
cout << "平衡因子有误:" << root->_key << endl;
return false;
}
return IsBalance(root->_left) && IsBalance(root->_right);//根节点正常就继续向下递归
}