平衡二叉树及其调整(含图含代码,C++实现)

373 阅读3分钟

前言

平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法)。在AVL树中,任一节点对应的两棵子树的最大高度差为1,因此它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下的时间复杂度都是O(logn)。 平衡因子(Balance Factor,简称BF): BF(T) = hL-hR,hL和hR分别代表左右子树高度 我们希望的平衡树是空树或者左右两边高度差不超过1,即 |BF(T)| <=1 如下,图a为AVL树,图b不是AVL树

在这里插入图片描述

图a

在这里插入图片描述

图b

为什么要有平衡二叉树

我们知道在二叉搜索树中,如果插入元素的顺序接近有序,那么二叉查找树将退化为链表,从而导致二叉查找树的查找效率大为降低。如何使得二叉查找树无论在什么样情况下都能使它的形态最大限度地接近满二叉树以保证它的查找效率呢?这就引出了一种平衡二叉树

平衡二叉树的基本操作

平衡二叉树其实也是搜索树,二叉搜索树所具有的操作,平衡二叉树也具有,但是有一点不同,在插入和删除之后,平衡二叉树的平衡性可能被破坏,需要调整,所以,我们对于平衡二叉树的操作,主要集中在调整上,至于查找,删除,插入操作,具体可以看二叉搜索树

先来看三种情况:

RR旋转

“7” 是插入的元素 在这里插入图片描述 一开始插入后,我们称“不平衡的==发现者==”在为“5”,因为他的BF值为-2,“==麻烦节点==”是 "7" 在发现在右子树的右子树上因而叫“==RR插入==”,需要进行“==RR旋转==”(右单旋)

//A为发现者,B为发现者的左节点
AVLTree* SingriRightRotation(AVLTree *A)
{ /* 注意:A必须有一个右子结点B */
  /* 将A与B做右单旋,更新A与B的高度,返回新的根结点B */
    AVLTree *B = A->Right;
    A->Right = B->Left;
    B->Left = A;    
    A->Height = max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
    B->Height = max(GetHeight(B->Left),A->Height) + 1;
    return B;
}

LL旋转

“2”为插入元素 在这里插入图片描述 “麻烦节点”在 “发现者” 的左子树的左子树上 叫“==LL插入==”,需要进行“==LL旋转==”

//A为发现者,B为发现者的左节点
AVLTree* SingleLeftRotation(AVLTree *A)
{ /* 注意:A必须有一个左子结点B */
  /* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */
    AVLTree *B = A->Left;
    A->Left = B->Right;
    B->Right = A;
    A->Height = max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
    B->Height = max(GetHeight(B->Left), A->Height) + 1;
    return B;
}

RL旋转 或 LR旋转

在这里插入图片描述 “麻烦节点”在“发现者”的左子树的右子树上,叫做“==LR插入==”,需要进行“==LR旋转==”。

AVLTree* DoubleLeftRightRotation(AVLTree *A)
{ 
    AVLTree* B = A->Left;
    A->Left = SingriRightRotation(B);
    return SingleLeftRotation(A);
}

至于RL旋转,就不必多说

Ps: 本篇文章写的并不是很具体,打算做为个人复习,若有发现错误欢迎指出,我将修改