数据结构——AVL树的插入
#include <iostream>
using namespace std;
#define LH +1 //左高
#define EH 0 //等高
#define RH -1 //右高
#define false 0
#define true 1
typedef struct BSTNode
{
int data; //节点的数据域
int bf; //平衡因子
BSTNode *lchild, *rchild; //节点的左、右孩子指针
}BSTNode, * BSTree; //将BSTree定义为结构体指针
//左旋转
void BSTree_L_Rotate(BSTree & root) //root为需要旋转的子树树根指针
{
BSTree rc=root->rchild; //将rc指身树的树根的右子树
root->rchild=rc->lchild; //将树的右子树的左子树挂到树根的右子树上
rc->lchild=root; //将root所指树挂到rc的左子树上
root=rc; //更新树根
}
//右旋转
void BSTree_R_Rotate(BSTree & root) //root为需要右旋的子树树根指针
{
BSTree lc=root->lchild; //lc指向root的右子树根
root->lchild=lc->rchild; //lc的右子树连接到root的左子树上
lc->rchild =root; //root连接到lc的右子树
root=lc; //更新树根
}
//左平衡处理
void LeftBalance(BSTree & root)
{
BSTree lc=root->lchild,rd=NULL; //lc指向root的左子树
switch(lc->bf)
{
case LH: //LL型
{
/*
* root--> * *
* / / \
* lc--> * ==> * *
* /
* *
*/
root->bf=lc->bf=EH; //更新平衡因子
BSTree_R_Rotate(root); //root作为根进行 右 旋转
break;
}
case RH: //LR型
{
rd = lc->rchild; //将rd指向lc的右子树
switch(rd->bf) //检查rd的平衡因子,并做相应的处理
{
case LH:
{
root->bf = RH; lc->bf = EH; break;
}
case EH:
{
root->bf = EH; lc->bf = EH; break;
}
case RH:
{
root->bf = EH; lc->bf = LH; break;
}
}//switch(rd->bf)
rd->bf = EH;
BSTree_L_Rotate(root->lchild); //以root的左子树根结点为根进行 左 旋转处理
BSTree_R_Rotate(root); //以root作为根进行 右 旋转处理
}
}//switch(lc->bf)
}//LeftBalance
//右平衡处理
void RightBalance(BSTree & root)
{
BSTree rc=root->rchild,ld=NULL;
switch(rc->bf)
{
case RH: //RR型
{
rc->bf=root->bf=EH;
BSTree_L_Rotate(root);
}
case LH: //RL型
{
ld=rc->lchild;
switch(ld->bf)
{
case LH:
{
root->bf=EH; rc->bf=LH; break;
}
case EH:
{
root->bf=EH; rc->bf=EH; break;
}
case RH:
{
root->bf=LH; rc->bf=EH; break;
}
}//switch(ld->bf)
ld->bf=EH;
BSTree_R_Rotate(root->rchild);
BSTree_L_Rotate(root);
}
}//switch(rc->bf)
}//RightBalance
//插入操作
int BSTree_Insert(BSTree &T, int taller, int data)
{
//now表示当前子树的根,taller为真时表示到目前为子树层数增加,为假则没增加
//插入成功返回真,否则返回假
if(!T) //now指针为空时在当前指针处插入新节点
{
T=(BSTree)malloc(sizeof(BSTNode)); //新建一个节点
T->bf=EH; //节点初始化操作,平衡因子赋为0
T->data=data;
T->lchild=T->rchild=NULL;
taller=true; //添加新节点,默认为增加子树的高度
return true; //插入成功,返回真
}
else
{
if(data == T->data) //树中已存在和e相同的关键字结点,则不再插入
{
taller=false;
return false;
}
else if(data < T->data) //当前待插入数据小于当前子树根的数据
{
if( !BSTree_Insert(T->lchild, taller, data) ) //递归,以当前树根的左子树根为新子树树根调用插入函数
return false; //没有插入成功
if(taller) //判断taller的值,为真时插入操作一定成功,并且进入平衡处理
{
switch(T->bf) //检查插入前当前树根的平衡因子
{
case RH:
{
T->bf=EH; //原本右子树比左子树高,现在左右子树等高,无须进一步平衡处理,修改平衡因子即可
taller=false; //子树高不改变,taller置为假
break;
}
case EH:
{
T->bf =LH; //原本左右子树等高,插入后左子树高增加,但此子树的局部平衡没被破坏,修改平衡因子即可
taller=true; //树高增加,taller置为真
break;
}
case LH:
{
LeftBalance(T); //原本左子树就比右子树高,插入后此子树局部平衡被破坏,需调用左平衡处理函数使之平衡
taller=false; //平衡处理后此子树高度不会增加,taller置为假
break;
}
}//switch(T->bf)
}//if(taller)
}//else if(data < T->data)
else //待插入数据大于当前子树根节点数据
{
if( !BSTree_Insert(T->rchild,taller,data) ) //递归,以当前树根的右子树根为新子树树根调用插入函数
return false; //没有插入成功
if(taller)
{
switch(T->bf) //检查插入前当前树根的平衡因子
{
case RH:
{
RightBalance(T); //原本右子树就比左子树高,插入后此子树局部平衡被破坏,需调用右平衡处理函数使之平衡
taller=false; //平衡处理后此子树高度不会增加,taller置为假
}
case EH:
{
T->bf=RH; //原本左右子树等高,插入后左子树高增加,但此子树的局部平衡没被破坏,修改平衡因子即可
taller=true; //树高增加,taller置为真
}
case LH:
{
T->bf=EH; //原本左子树就比右子树高,现在左右子树等高,无须进一步平衡处理,修改平衡因子即可
taller=false; //子树高不改变,taller置为假
}
}//switch(T->bf)
}//if(taller)
}//else
}//else
return true;
}//BSTree_Insert
//中序遍历
void mind_Traverse(BSTree &root)
{
if(root)
{
mind_Traverse(root->lchild);
cout<<root->data<<" ";
mind_Traverse(root->rchild);
}
}
//前序遍历
void pre_Traverse(BSTree &root)
{
if(root)
{
cout<<root->data<<" ";
pre_Traverse(root->lchild);
pre_Traverse(root->rchild);
}
}
int main()
{
BSTree root;
root=NULL;
BSTree_Insert(root,0,34);
BSTree_Insert(root,0,18);
BSTree_Insert(root,0,13);
BSTree_Insert(root,0,73);
BSTree_Insert(root,0,16);
BSTree_Insert(root,0,52);
BSTree_Insert(root,0,58);
BSTree_Insert(root,0,67);
BSTree_Insert(root,0,82);
BSTree_Insert(root,0,76);
BSTree_Insert(root,0,93);
mind_Traverse(root);
cout<<endl;
return 0;
}