zoukankan      html  css  js  c++  java
  • AVL树 高度平衡的二叉查找树

    1、What is AVL tree?

    AVL tree 是一种特殊的二叉查找树,,首先我们要在树中引入平衡因子balance,表示结点右子树的高度减去左子树的高度差(右-左),对于一棵AVL树要么它是一棵空树,要么它是一棵高度平衡的二叉查找树,平衡因子balance绝对值不超过1

                                       

    非平衡的二叉查找树                                                            平衡的二叉查找树

    根据定义,任意结点的平衡因子只能取-1、0、1

    AVL搜索算法复杂度为log(n)

    2、AVL树的插入

    在向一棵AVL树中插入一个新结点时,如果树中某个结点的平衡因子的绝对值|balance|>1,则出现了不平衡,需要做平衡化处理。

    在插入的位置可能要进行平衡旋转

    每插入一个新结点时,AVL树中相关结点的平衡状态发生改变,因此,在插入一个新结点后,需要从插入位置沿通向根的路径回溯,检查各结点的平衡因子。

    (1)右单旋转

    (盗图)

    插入了结点2,AVL树失衡了,现在要通过右单旋转将其化为AVL树

    以结点3为旋转轴,将结点2与结点5顺时针旋转

    将3变为根,5变为叶子节点

    转后结果:

    //右单旋转
    void R_Rotate(BSTree &p)
    {
    	BSTree rc;
    	rc=p->lchild;
    	p->lchild=rc->rchild;
    	rc->rchild=p;
    	p=rc;
    }
    

      

    (2)左单旋转

    与右单旋转类似

    算法

    //左单旋转
    void L_Rotate(BSTree &p)
    {
    	BSTree lc;
    	lc=p->rchild;
    	p->rchild=lc->lchild;
    	lc->lchild=p;
    	p=lc;
    }
    

     

    (3)双旋转

    如果是如下方式插入那么怎么办呢?

    (盗图)

    很明显的是单用左单旋转与右单旋转是无法解决问题的

    要用左单与右单结合来做

    对于上图中的情况先左旋在右旋

    左旋:

    其实就是化为能够进行右旋的形式

    右旋:

    3、分析

    失去平衡的最小子树的根结点必然离插入结点最近,平衡因子的绝对值在插入之前大于0

    (1)在查找S结点的插入位置过程中,记录与S结点最近,且平衡因子不等于零的结点a

    (2)修改自a到S的路径上所有结点的平衡因子

    (3)判断树是否出现不平衡,即a的平衡因子是否大于1

    (4)若出现不平衡,进行平衡调整

  • 相关阅读:
    页面加载完毕相关信息淡入效果
    导航菜单底部滑动条跟随效果
    我要成为优秀的前端一员!
    (转)git合并多个commit
    Windows 7 + PHP 5.3 + WAMP 下 Imagick 扩展安装
    使用 PHP 框架 Yii 访问 MS SQL 的尝试
    拼合逐月数据系列
    编程视频教程推荐
    Java 实现 Domino邮箱自动注册
    二、 编写一个类,用两个栈实现队列,支持队列的基本操作(add,poll,peek)
  • 原文地址:https://www.cnblogs.com/KennyRom/p/6083064.html
Copyright © 2011-2022 走看看