实现代码如下:
//RR型调整函数//返回新父节点
Tree RR_rotate(Tree node){
//node为离操作结点最近的失衡的结点
Tree parent=NULL,son;
//获取失衡结点的父节点
parent=node->parent;
//获取失衡结点的右孩子
son=node->rchild;
//设置son结点左孩子的父指针
if (son->lchild!=NULL){
son->lchild->parent=node;
}
//失衡结点的右孩子变更为son的左孩子
node->rchild=son->lchild;
//更新失衡结点的高度信息
update_depth(node);
//失衡结点变成son的左孩子
son->lchild=node;
//设置son的父结点为原失衡结点的父结点
son->parent=parent;
//如果失衡结点不是根结点,则开始更新父节点
if (parent!=NULL){
//如果父节点的左孩子是失衡结点,指向现在更新后的新孩子son
if (parent->lchild==node){
parent->lchild=son;
}else{
//父节点的右孩子是失衡结点
parent->rchild=son;
}
}
//设置失衡结点的父亲
node->parent=son;
//更新son结点的高度信息
update_depth(son);
return son;
}
6.3 A的左孩子的右子树插入节点(LR)
若 A 的左孩子节点 B 的右子树 E 插入节点 F ,导致节点 A 失衡,如图:
图 6.3A 的平衡因子为 2 ,若仍按照右旋调整,则变化后的图形为这样:
图 6.3.1经过右旋调整发现,调整后树仍然失衡,说明这种情况单纯的进行右旋操作不能使树重新平衡。那么这种插入方式需要执行两步操作,使得旋转之后为 原来根结点的左孩子的右孩子作为新的根节点。
(1)对失衡节点 A 的左孩子 B 进行左旋操作,即上述 RR 情形操作。
(2)对失衡节点 A 做右旋操作,即上述 LL 情形操作。
调整过程如下:
图 6.3.2 图 6.3.3也就是说,经过这两步操作,使得 原来根节点的左孩子的右孩子 E 节点成为了新的根节点。
代码实现:
//LR型,先左旋转,再右旋转//返回:新父节点
Tree LR_rotate(Tree node){
RR_rotate(node->lchild);
return LL_rotate(node);
}
6.4 A的右孩子的左子树插入节点(RL)
右孩子插入左节点的过程与左孩子插入右节点过程类似,也是需要执行两步操作,使得旋转之后为 原来根结点的右孩子的左孩子作为新的根节点。
(1)对失衡节点 A 的右孩子 C 进行右旋操作,即上述 LL 情形操作。
(2)对失衡节点 A 做左旋操作,即上述 RR 情形操作。
也就是说,经过这两步操作,使得 原来根节点的右孩子的左孩子 D 节点成为了新的根节点。