您的位置:首页 > 其它

平衡二叉树AVL的基本操作之插入

2014-07-07 20:42 495 查看
平衡二叉树或是一棵空树,或是具有下列性质的二叉排序树:其左子树和右子树都是平衡二叉树,而且左右子树深度之差绝对值不超过1. 由此引出了平衡因子(balance factor)的概念,bf定义为该结点的左子树的深度减去右子树的深度(有些书是右子树深度减去左子树深度,我是按照左子树减去右子树来计算的,下面的代码也是这样定义的),所以平衡二叉树的结点的平衡因子只可能是 -1,0,1 ,某个结点的平衡因子绝对值大于1,该二叉树就不平衡。

平衡二叉树在出现不平衡状态的时候,要进行平衡旋转处理,有四种平衡旋转处理(单向右旋处理,单向左旋处理,双向旋转(先左后右)处理,双向旋转(先右后左)处理),归根到底是两种(单向左旋处理和单向右旋处理)。

下面是四种旋转的示意图:



图1 LL旋转 和 RR旋转



图2 LR旋转



图3 LR旋转和LL旋转



图4 RL旋转



图5 LR旋转

这四种旋转可以归纳为两类:LL旋转和LR旋转可以归为左旋转,RR旋转和RL旋转归为右旋转。

类型定义:

typedef struct AVLNode * AVLTree;

typedef struct AVLNode{
int data;
short int bf;
AVLTree lchild,rchild;
}AVLNode;
左旋函数:

void leftRotate(AVLTree *root,bool *unbalanced)
{
AVLTree child,gchild;//gchild : grand child
child = (*root)->lchild;
if (child->bf == 1) {
/* LL rotation */
(*root)->lchild = child->rchild;
child->rchild = *root;
(*root)->bf = 0;
(*root) = child;
}
else {
/* LR rotation */
gchild = child->rchild;
child->rchild = gchild->lchild;
gchild->lchild = child;
(*root)->lchild = gchild->rchild;
gchild->rchild = *root;
switch (gchild->bf) {
case 1:		(*root)->bf = -1;
child->bf = 0;
break;
case 0:		(*root)->bf = child->bf = 0;
break;
case -1:	(*root)->bf = 0;
child->bf = 1;
}
*root = gchild;

}
(*root)->bf = 0;
*unbalanced = false;
}


右旋函数:

void rightRotate(AVLTree *root, bool *unbalanced)
{
AVLTree child,gchild;/*gchild : grand child*/
child = (*root)->rchild;
if (child->bf == -1) {
/* RR rotation */
(*root)->rchild = child->lchild;
child->lchild = *root;
(*root)->bf = 0;
(*root) = child;
}
else {
/* RL rotation */
gchild = child->lchild;
child->lchild = gchild->rchild;
gchild->rchild = child;
(*root)->rchild = gchild->lchild;
gchild->lchild = *root;
switch (gchild->bf) {
case -1:	(*root)->bf = 1;
child->bf = 0;
break;
case 0:		(*root)->bf = child->bf = 0;
break;
case 1:		(*root)->bf = 0;
child->bf = -1;
}
*root = gchild;

}
(*root)->bf = 0;
*unbalanced = false;
}


AVL树的插入函数:

void AVLInsert(AVLTree *root, int x, bool *unbalanced)
{
if(*root == NULL){
/* insert into a null tree */
*unbalanced = true;
*root = new AVLNode;
(*root)->lchild = (*root)->rchild = NULL;
(*root)->bf = 0;
(*root)->data = x;
}
else if (x < (*root)->data) {
AVLInsert(&((*root)->lchild),x,unbalanced);
if (*unbalanced)
/* left branch has grown higher */
switch ((*root)->bf) {
case -1: 	(*root)->bf = 0;
*unbalanced  = false;
break;
case 0: 	(*root)->bf = 1;
break;
case 1:		leftRotate(root,unbalanced);
}
}
else if (x > (*root)->data) {
AVLInsert(&((*root)->rchild), x, unbalanced);
if (*unbalanced)
/* right branch has grown higher */
switch ((*root)->bf){
case 1: 	(*root)->bf = 0;
*unbalanced = false;
break;
case 0:		(*root)->bf = -1;
break;
case -1:	rightRotate(root,unbalanced);
}
}
else {
*unbalanced = false;
cout<<"Node x = "<<x<<" is alreay in the tree."<<endl;
}
}


测试结果:

从0到9到插入结果

0
---------------------cut---------------------
0
\
1
---------------------cut---------------------
1
/   \
0   2
---------------------cut---------------------
1
/   \
0       2
\
3
---------------------cut---------------------
1
/   \
0       3
/   \
2   4
---------------------cut---------------------
3
/   \
1       4
/   \       \
0   2       5
---------------------cut---------------------
3
/   \
1       5
/   \   /   \
0   2   4   6
---------------------cut---------------------
3
/   \
1               5
/   \           /   \
0       2       4       6
\
7
---------------------cut---------------------
3
/   \
1               5
/   \           /   \
0       2       4       7
/   \
6   8
---------------------cut---------------------
3
/   \
1               7
/   \           /   \
0       2       5       8
/   \       \
4   6       9
---------------------cut---------------------


REF:

1,http://blog.csdn.net/jkay_wong/article/details/6676488

2,数据结构(C语言版) Ellis Horowitz
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: