平衡二叉树
或者是一颗空树,或者它的左右子树都是平衡二叉树,且左子树和右子树的深度之差不超过1 。
BF(Balance Factor)
我们将二叉树上节点的左子树深度减去右子树深度的值成为平衡因子。那么平衡二叉树上所有节点的平衡因子只可能是-1,0,1.只要二叉树上有一个节点的平衡引子的绝对值大于1,则该二叉树就是不平衡的。
距离插入节点最近的,且平衡因子的绝对值大于1的节点为根的子树,我们成为最小不平衡子树。最小不平衡子树的树根是我们操作平衡转换的参照点,调整最小不平衡子树,然后就可以达到平衡的效果。
首先要明白,如果需要调整平衡二叉树,那么这颗二叉树肯定是刚刚开始不平衡的,我们只需要调整因为插入新节点导致的最小不平衡子树的结构即可。
树的节点结构,相比于二叉查找树,增加一bf,用来存储平衡因子。
/* 二叉树的二叉链表节点结构定义 */
typedef struct BiTNode
{
int data;
int bf; /* 相对于二叉查找树,增加了平衡因子bf */
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
两个基本操作,左旋和右旋。
右旋图示:
代码如下:
/* 对以p为根的二叉排序树作右旋处理 */
/* 处理之后p指向新的树根节点,即旋转处理之前的左子树的根节点 */
void R_Rotate( BiTree *p )
{
/*
L->rchild (节点2的右孩子) 为NULL L->rchild != NULL
例 : 3 例 : 9 6
/ / \ / \
2 => 2 6 10 => 5 9
/ / \ / \ / / \
1 1 3 5 7 4 7 10
/
4
*/
BiTree L;
L = (*p)->lchild;
(*p)->lchild = L->rchild; /* 容易忽视,将*p的左子树的右子树作为*p的左子树(如果 L->rchild 不为空) */
L->rchild = (*p);
*p = L;
}
左旋图示: