数据结构——平衡二叉树(AVL树)

前言:

    由于二叉查找树不是严格意义上的O(logN),为了查找时间复杂度能够严格意义上的O(logN),在二叉查找树的基础上进行改进,附加一个性质,即某棵树根节点的左右子树高度相差不能大于1。如果左右子树高度相差大于1,则需进行旋转调整。

定义:

平衡二叉树是一棵二叉查找树,且根节点的左右子树高度相差不能大于1。

其结构图如下:

《数据结构——平衡二叉树(AVL树)》

    当在AVL树中进行插入操作和删除操作时,有时候会失去平衡性,即父节点的左右子树高度相差大于1,此时就必须对该AVL树进行调整,使其满足AVL树的性质。这里采用旋转进行调整。

旋转:

平衡二叉树失去平衡性具有以下四种情况:

  1. 左子树的高度大于右子树高度,且相差大于1,同时左子树根节点的左孩子节点高度大于右孩子节点高度。此情况称为左左情况。
  2. 左子树的高度大于右子树高度,且相差大于1,同时左子树根节点的右孩子节点高度大于左孩子节点高度。此情况称为左右情况。
  3. 右子树的高度大于左子树高度,且相差大于1,同时右子树根节点的左孩子节点高度大于右孩子节点高度。此情况称为右左情况。
  4. 右子树的高度大于左子树高度,且相差大于1,同时右子树根节点的右孩子节点高度大于左孩子节点高度。此情况称为右右情况。

下图是对应上面四种不同情况的失衡结构图:

《数据结构——平衡二叉树(AVL树)》

图2说明:

  1. 第一小图属于左左情况,根节点11的左子树(以节点6为根节点的树)高度大于右子树(以节点15为根节点的树)高度,且相差为2,同时左子树的根节点6的左孩子节点2的高度大于右孩子节点7的高度。
  2. 第二小图属于左右情况,根节点11的左子树(以节点6为根节点的树)高度大于右子树(以节点15为根节点的树)高度,且相差为2,同时左子树的根节点6的右孩子节点7的高度大于左孩子节点2的高度。
  3. 第三小图属于右左情况,根节点11的右子树(以节点15为根节点的树)高度大于左子树(以节点6为根节点的树)高度,且相差为2,同时右子树的根节点15的左孩子节点14的高度大于右孩子节点17的高度。
  4. 第四小图属于右右情况,根节点11的右子树(以节点15为根节点的树)高度大于左子树(以节点6为根节点的树)高度,且相差为2,同时右子树的根节点15的右孩子节点17的高度大于左孩子节点12的高度。

    从图2分析可知,情况1(左左)和情况4(右右)是对称的,只需旋转一次即可,我们称为单旋转。情况2(左右)和情况3(右左)是对称的,需要旋转两次,我们称为双旋转。

单旋转:

单旋转是针对左左和右右情况的,只需旋转一次即可达到平衡。

情况1:左左

《数据结构——平衡二叉树(AVL树)》

    说明:此情况的二叉树是不平衡二叉树,旋转过程中,把左孩子节点6作为二叉树新的根节点,节点6的左子树不变,节点6的右子树作为二叉树原根节点11的的左子树,二叉树原根节点11作为新的二叉树的右子树。

情况4:右右

《数据结构——平衡二叉树(AVL树)》

    说明:此情况的二叉树是不平衡二叉树,旋转过程中,把右孩子节点15作为二叉树新的根节点,节点15的右子树不变,节点15的左子树作为二叉树原根节点11的的右子树,二叉树原根节点11作为新的二叉树的左子树。

双旋转:

双旋转是指不平衡二叉树必须经过两次旋转才能达到平衡。

情况2:左右

《数据结构——平衡二叉树(AVL树)》

    说明:首先对左子树节点6进行右右旋转的操作,在对二叉树根节点11进行左左旋转的操作。

情况3:右左

《数据结构——平衡二叉树(AVL树)》

   说明:首先对右子树节点15进行左左旋转的操作,在对二叉树根节点11进行右右旋转的操作。

相关操作:

    平衡二叉树的插入、查找和删除操作跟二叉查找树的操作类似,只是在操作结束时,对二叉树进行调整,使其仍然是平衡二叉树。有关二叉查找树的操作在前面的博文《二叉查找树》已经记录过,在这里就不做记录。

    原文作者:AVL树
    原文地址: https://blog.csdn.net/chenhanzhun/article/details/38615717
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞