完整代码在最后。
教材里的左转右转也是看的一头雾水,画一下图就很明白了,不用去记左右旋转及其对应的情形,知道怎么变就行了。
P
//
// Created by dgm on 19-4-10.
//
#include <iostream>
using namespace std;
#define LH 1
#define EH 0
#define RH -1
typedef char ElemType;
typedef struct BiNode{
ElemType data;
BiNode*lchild,*rchild;
int bf;
}BiNode,*BiTree;
void L_Rotate_For_Left(BiTree&p)//the element is added to p->lchild->lchild
{
auto lc=p->lchild;
p->lchild=lc->rchild;
lc->rchild=p;
p=lc;
}
void R_Rotate_For_Right(BiTree&p)//the element is added to p->rchild->rchild
{
auto rc=p->rchild;
p->rchild=rc->lchild;
rc->lchild=p;
p=rc;
}
void R_Rotate_For_Left(BiTree&p)//the element is added to p->lchild->rchild
{
auto lc=p->lchild;
auto lcrc=lc->rchild;
lc->rchild=lcrc->lchild;
p->lchild=lcrc->rchild;
lcrc->lchild=lc;
lcrc->rchild=p;
p=lcrc;
}
void L_Rotate_For_Right(BiTree&p)//the element is added to p->rchild->lchild
{
auto rc=p->rchild;
auto rclc=rc->lchild;
p->rchild=rclc->lchild;
rc->lchild=rclc->rchild;
rc->lchild=p;
rc->rchild=rc;
p=rclc;
}
void LeftBalance(BiTree&T) //when the new node was added to the left child of root(or T)
{
auto lc=T->lchild;
switch (lc->bf)
{
case LH: //if it was added to T->lchild->lchild, just as picture1
T->bf=lc->bf=EH;
L_Rotate_For_Left(T);
break;
case RH: //if it was added to T->lchild->lchild, just as picture2
auto rc=lc->rchild;
switch (rc->bf)
{
case LH: //present T points to the new tree's right child after rotate, and lc points to left child
//as picture2 shows
T->bf=RH;lc->bf=EH;
break;
case RH: //the other situation of picture2
T->bf=EH;lc->bf=LH;
break;
}
rc->bf=EH; //the root
R_Rotate_For_Left(T); //after that, the old root T points to the new root;
break;
}
}
void RightBalance(BiTree&T) //as above
{
auto rc=T->rchild;
switch (rc->bf)
{
case RH:
R_Rotate_For_Right(T);
T->bf=rc->bf=EH;
break;
case LH:
auto lc=rc->lchild;
switch (lc->bf)
{
case LH:
T->bf=EH;rc->bf=RH;
break;
case RH:
T->bf=LH;rc->bf=EH;
break;
}
lc->bf=EH;
L_Rotate_For_Right(T);
break;
}
}
bool InsertAVL(BiTree&T,ElemType e, bool&taller)
{
if(!T){ //if the tree is null
T=new BiNode(); //new a node
T->data=e;
T->lchild=T->rchild=NULL;
T->bf=EH;
taller= true; //height be taller
}
else{
if(T->data==e){ //the element was in the tree already
taller= false;return 0; //not be taller
}
if(T->data>e) { //added to left (elements in left is less than T)
if (!InsertAVL(T->lchild, e, taller))return 0; //already have
if (taller) { //add successfully
switch (T->bf) {
case LH: //added to left tree
LeftBalance(T); //...
taller = false; //the root is balanced
break;
case EH: //notice it is added to T's left tree
T->bf = LH; //so if T is balanced previously
taller = true; //T's left tree will be taller
break;
case RH: //T's right tree is taller previously
T->bf = EH; //and the element is added to T's left tree
taller = false; //so it is equal in height
break;
}
}
}
else{ //as above
if (!InsertAVL(T->rchild,e,taller))return 0;
if(taller){
switch (T->bf){
case LH:
T->bf=EH;
taller= false;
break;
case EH:
T->bf=RH;
taller=true;
break;
case RH:
RightBalance(T);
taller= false;
break;
}
}
}
}
return true;
}
void CreateTree(BiTree&T,char arr[],int &index) //create tree (or using InsertAVL)
{
if(arr[index]=='#'){
T=NULL;
}
else{
T=new BiNode();
T->data=arr[index];
T->bf=EH;
CreateTree(T->lchild,arr,++index);
CreateTree(T->rchild,arr,++index);
}
return ;
}
//void PreTraverse(BiTree T)
//{
// if(T)
// {
// cout<<T->data<<" ";
// PreTraverse(T->lchild);
// PreTraverse(T->rchild);
// }
//}
int main()
{
BiTree T;
T=NULL; //??如果不写这句T的值是多少,貌似默认不是NULL,因为不写这句就会出错,奇怪??
bool taller= false;
char arr[]="64##8##"; //也可以直接通过Insert来创建树
int index=0;
CreateTree(T,arr,index); //左子树高,输出1
cout<<T->bf<<endl; //右子树高,输出-1
InsertAVL(T,'3',taller); //等高当然是输出0
cout<<T->bf<<endl;
InsertAVL(T,'5',taller);
cout<<T->bf<<endl;
InsertAVL(T,'2',taller);
cout<<T->bf<<endl;
InsertAVL(T,'9',taller);
cout<<T->bf<<endl;
cout<<"吆西yaoxi吆西"<<endl;
return 0;
}