什么是平衡二叉树(AVL) (3)

实现代码如下:

//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.3

图 6.3

A 的平衡因子为 2 ,若仍按照右旋调整,则变化后的图形为这样:

图 6.3.1

图 6.3.1

经过右旋调整发现,调整后树仍然失衡,说明这种情况单纯的进行右旋操作不能使树重新平衡。那么这种插入方式需要执行两步操作,使得旋转之后为 原来根结点的左孩子的右孩子作为新的根节点

(1)对失衡节点 A 的左孩子 B 进行左旋操作,即上述 RR 情形操作。
(2)对失衡节点 A 做右旋操作,即上述 LL 情形操作。

调整过程如下:

图 6.3.2

图 6.3.2

图 6.3.3

图 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 情形操作。

图 6.4

图 6.4

图 6.4.1

图 6.4.1

图 6.4.2

图 6.4.2

也就是说,经过这两步操作,使得 原来根节点的右孩子的左孩子 D 节点成为了新的根节点

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgpwx.html