STL关联式容器(二)

平衡二叉搜索树
也许因为输入值不够随机,也许因为经过某些插入或删除操作,二叉搜索树可能会失去平衡造成搜寻效率低落的情况:
树的极度平衡与极度不平衡
所谓树形平衡与否,并没有一个绝对的标准。“平衡”的大致意义是:没有任何一个节点过深或深度过大。不同的平衡条件,造成不同的效率表现,以及不同的实现复杂度。有数种特殊结构如AVL-tree、RB-tree、AA-tree,均可实现出平衡二叉搜索树,它们都比一般的(无法绝对维持平衡的)二叉搜索树复杂。因此,插入节点和删除节点的平均时间也比较长,但是它们总是保持某种程度的平衡,所以元素的访问(搜寻)时间平均而言也就比较少。
AVL tree(Adelson-Velskii-Landis tree)
AVL tree是一个“加上了额外平衡条件”的二叉搜索树。其平衡条件的建立是为了确保整棵树的深度为O(log N)。直观上的最佳平衡条件是每个节点的左右子树有着相同的高度,但这未免太过严苛,我们很难插入新元素而又保持这样的平衡条件。AVL tree于是退而求其次,要求任何节点的左右子树高度相差最多1。这是一个较弱的条件,但仍能够保证“对数深度(logarithmic depth)”平衡状态。
下图所示是一个AVL tree,插入节点11后,灰色节点违反AVL tree 的平衡条件。由于只有“插入点至根节点”路径上的各节点可能改变平衡状态,因此,只要调整其中最深的那个节点,便可使整棵树重新获得平衡。
在这里插入图片描述前面说过,只要调整“插入点至根节点”路径上,平衡状态被破坏至各节点中最深的那一个,便可使整棵树重新获得平衡。假设该最深节点为X,由于节点多拥有两个子节点,而所谓“平衡被破坏”意味着X的左右两棵子树的高度相差2,因此我们可以轻易将情况分四种:

  1. 插入点位于X的左子节点的左子树——左左;
  2. 插入点位于X的左子节点的右子树——左右;
  3. 插入点位于X的右子节点的左子树——右左;
  4. 插入点位于X的右子节点的右子树——右右;
    情况1、4对称,称为外侧插入(outside)插入,可以采用单旋转操作(single rotation)调整解决。情况2,3彼此对称,称为内侧(inside)插入,可以采用双旋转操作(double rotation)调整解决。
    在这里插入图片描述
    单旋转(Single Rotation)
    在外侧插入状态,k2“插入前平衡,插入后不平衡”的唯一情况如下图左侧所示。A子树成长了一层,致使它比C子树的深度多2.B子树不可能和A子树位于同一层,否则k2在插入前就处于不平衡状态了。B子树也不可能和C子树位于同一层,否则第一个违反平衡条件的将是k1而不是k2.
    在这里插入图片描述
    为了调整平衡状态,我们希望将A子树提高一层,并将C子树下降一层。这已经比AVL tree所要求的平衡条件更进一步了,上图右侧为调整后的情况。我们可以这么想象,把k1提起,使k2自然下滑,并将B子树挂在k2的左侧。这么做是因为,二叉搜索树的规则使我们知道,k2>k1,所以k2必须成为新树形中的k1的右子节点。二叉搜索树的规则也告诉我们,B子树的所有节点的键值都在k1和k2之间,所以新树形中的B子树必须落在k2的左侧。
    双旋转(Double Rotation)
    下图左侧为内侧插入所造成的不平衡状态,单旋转无法解决这种情况。一是我们不能再以k3为根节点,其次,我们不能将k3和k1做一次单旋转,因为旋转之后还是不平衡。唯一的可能是以k2为新的根节点,这使得k1必须为k2的左子节点,k3必须成为k2的右子节点,而这么一来也就完全决定了四个子树的位置。新的树形满足AVL-tree的平衡条件,并且,就像单旋转的情况一样,它恢复了节点插入之前的高度,因此,保证不再需要任何调整:
    在这里插入图片描述
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值