平衡二叉树
平衡二叉树的定义:
1. 左子树的值都小于根
2. 右子树的值都大于根
3. 左子树跟右子树的高度差不超过1
4.左子树、右子树也是平衡二叉树
由此可见,平衡二叉树的定义也是一个递归定义。
平衡二叉树的调整(分两种情况):
1)当根节点平衡因子为1时,在左子树添加节点,导致左子树更高,根节点的平衡因子变成2,需要调整
2)当根节点平衡因子为-1, 在右子树上添加节点,导致右子树更高,根节点平衡因子变成-2,需要调整。
Case1:
上图将第一种情况进行了细分,下面针对图1.1,1.2,1.3单独分析
图1.1
在B的左子树上添加节点,导致A的平衡因子变为2,需要调整,进行顺时针右旋调整
在B的右子树添加节点,该情况可以细化为如下三种情况:对于图中标红框,表示在此处添加节点,不影响树的平衡系数。
图1.1.1分析
在C节点的左子树加节点的情况分析。对于图1.1.2 C的右子树添加节点以及图1.1.3 C的左子树添加节点,分析与在图1.1.1上一样,所以全部集中到图1.1.1上进行。在C的左子树添加节点,
在C树的右子树上添加节点
图1.1.1,在C的左子树和右子树上添加节点,处理方法完全一样,先对tree的左孩子节点进行逆时针左旋,再对tree进行顺时针右旋。
图1.2
在B的左子树上添加节点,不会影响树的平衡系数。
在B的右子树上添加节点,与图1.1中处理在B的右子树添加节点一致。
图1.3
在B的右子树上添加节点,不会影响树的平衡系数在B的左子树添加节点,与图1.1中处理在B的左子树中添加节点一致。
Case2:
A的平衡系数为-1,在A的右子树中再添加一个节点,导致平衡系数变成-2,需要调整
具体细化成如下三种情况。
先做说明:对B的左子树添加节点,图2.1,2.2处理方法是一样的。
对B的右子树添加节点,图2.1, 2.3处理方法是一致的。
对2.2对B右子树添加节点,与图2.3B左子树添加节点,不会影响树的平衡因子,不做处理。
所以此处只以图2.1为例进行说明。
在B的右子树添加节点:逆时针左旋
在B的左子树上添加节点:(由上文分析可知,在C的左子树或者右子树添加节点,处理方法一致,此处不做冗余说明)
先做顺时针右旋,再说逆时针左旋,让树平衡。
由上图分析可知,对于平衡二叉树的调整,总结下来,只有四种情况:
1. tree bf = 1(左子树偏高),在tree->lchild的左子树上添加节点,并且树变高,只需做顺时针右旋操作,即可将树的平衡因子降下来2. tree bf = 1,在tree->lchild的右子树添加节点,并且树变高,需要做两次变换,先对lchild做逆时针左旋,在对tree做顺时针右旋
3. tree bf = -1(右子树偏高),在tree->rchild的右子树添加节点,并且树变高,对tree做逆时针左旋
4. tree bf = -1, 在tree->rchild的左子树添加节点,并且树变高,需要做两次变换,先对rchild做顺时针右旋,再对tree做
逆时针左旋
具体调整方法如下:
情况一、二处理方法如下:
void leftBalance(avlTreeNode* &tree)
{
avlTreeNode* lc = tree->left;
switch(lc->bf)
{
case LH:
tree->bf = EH;
tree->left->bf = EH;
LL(tree);
break;
case RH:
avlTreeNode* rc_lc = lc->right;
tree->bf = EH;
tree->left->bf = EH;
tree->left->right->bf = RH;
RR(lc);
LL(tree);
break;
}
}
情况三、四处理方法:
void rightBalance(avlTreeNode* &tree)
{
avlTreeNode* rc = tree->right;
switch(rc->bf)
{
case LH:
tree->bf = EH;
tree->right->bf = RH;
tree->right->left->bf = EH;
LL(rc);
RR(tree);
break;
case RH:
tree->bf = EH;
tree->right->bf = EH;
RR(tree);
break;
}
}
LL:逆时针左旋
void LL(avlTreeNode* &tree)
{
avlTreeNode* lc = tree->left;
tree->left = lc->right;
lc->right = tree;
tree = lc;
};
RR:顺时针右旋
void RR(avlTreeNode* &tree)
{
avlTreeNode* rc = tree->right;
tree->right = rc->left;
rc->left = tree;
tree = rc;
};