#include <iostream>
#include <algorithm>
#include <vector>
//平衡二叉排序树
struct NODE
{
int val;
int bf;//平衡因子,当所有节点的平衡因子为-1、0、1时,此二叉排序树是平衡二叉排序树
NODE *lchild, *rchild;
};
void R_Rotate(NODE **p)
{
//右旋
NODE *q = (*p)->lchild;
(*p)->lchild = q->rchild;
q->rchild = *p;
*p = q;
}
void L_Rotate(NODE **p)
{
//左旋
NODE *q = (*p)->rchild;
(*p)->rchild = q->lchild;
q->lchild = *p;
*p = q;
}
void LeftBalance(NODE **T)
{
//对以指针T所指节点为根的二叉树做左平衡旋转处理
//此时T->bf > 1
//需考察T->lchild->bf与T->bf符号相同与不相同两种情况
NODE *L = (*T)->lchild;
switch(L->bf)
{
case 1:
{
//新插入的节点在T的左孩子的左子树上
//符号相同,直接右旋
L->bf = (*T)->bf = 0;
R_Rotate(T);
break;
}
case -1:
{
//新插入节点在T的左孩子的右子树上
//符号不同,需先对L左旋,调整L->bf与T->bf符号相同,再对T右旋
NODE *Lr = L->rchild;
switch (Lr->bf)
{
case 1:
{
L->bf = 0;
(*T)->bf = -1;
break;
}
case -1:
{
L->bf = 1;
(*T)->bf = 0;
break;
}
case 0:
{
(*T)->bf = L->bf = 0;
break;
}
default:
break;
}
Lr->bf = 0;
L_Rotate(&(*T)->lchild);
R_Rotate(T);
break;
}
case 0:
{
(*T)->bf = 1;
L->bf = -1;
R_Rotate(T);
break;
}
}
}
void RightBalance(NODE **T)
{
//对以指针T所指节点为根的二叉树做右平衡旋转处理
//此时T->bf < -1
//需考察T->lchild->bf与T->bf符号相同与不相同两种情况
NODE *R = (*T)->rchild;
switch (R->bf)
{
case 1:
{
//新插入的节点在T右子树的左孩子上
//R->bf与T->bf符号不同,需进行双旋转
NODE *rl = R->lchild;
switch (rl->bf)
{
case 1:
{
R->bf = -1;
(*T)->bf = 0;
break;
}
case -1:
{
R->bf = 0;
(*T)->bf = 1;
break;
}
case 0:
{
(*T)->bf = R->bf = 0;
break;
}
default:
break;
}
rl->bf = 0;
R_Rotate(&(*T)->rchild);
L_Rotate(T);
break;
}
case -1:
{
//新插入的节点在T右子树的右还是上
//R->bf与T->bf符号相同,直接旋转
(*T)->bf = R->bf = 0;
L_Rotate(T);
break;
}
case 0:
{
(*T)->bf = -1;
R->bf = 1;
L_Rotate(T);
break;
}
default:
break;
}
}
//taller用于记录树是否长高,即是否插入成功
//如果插入成功后,需递归回溯进行平衡调整,修改BF值
int InsertAVL(NODE **T, int key, int &taller)
{
if(!(*T))
{
*T = new NODE;
(*T)->val = key;
(*T)->bf = 0;
(*T)->lchild = (*T)->rchild = NULL;
taller = 1;
}
else
{
if(key == (*T)->val)
{
//树中已经有key了,插入失败
taller = 0;
return 0;
}
else if(key < (*T)->val)
{
if(!InsertAVL(&(*T)->lchild, key, taller))
{
//左子树中插入失败
return 0;
}
else
{
//左子树中插入成功
if(taller)
{
//树长高, 此时需修改T的BF
switch((*T)->bf)
{
//判断当前*T的BF值
case 0:
{
//原本左右子树等高,现因左子树增高而树增高
(*T)->bf = 1;
break;
}
case 1:
{
//原本左子树比右子树高,需作平衡处理
LeftBalance(T);
taller = 0;
break;
}
case -1:
{
//原本右子树比左子树高,现在左子树增高,左右子树等高
(*T)->bf = 0;
taller = 0;
break;
}
default:
break;
}
}
}
}
else
{
if(!InsertAVL(&(*T)->rchild, key, taller))
{
//插入失败
return false;
}
else
{
if(taller)
{
switch((*T)->bf)
{
case 0:
{
//原本等高,现在右子树比左子树高
(*T)->bf = -1;
break;
}
case 1:
{
//原本左子树高,现在等高
(*T)->bf = 0;
taller = 0;
break;
}
case -1:
{
//原本右子树高,现在右边插入,需调整
RightBalance(T);
taller = 0;
break;
}
default:
break;
}
}
}
}
}
}
//smaller用于标记树是否变矮
int DeleteAVL(NODE **T, int key, int &smaller)
{
if(!*T)
{
return 0;
}
else if((*T)->val > key)
{
//左子树中删除
if(!DeleteAVL(&(*T)->lchild, key, smaller))
{
return 0;
}
else
{
if(smaller)
{
//如果左子树高度降低了,需考察当前结点的高度,看是否进行旋转
switch ((*T)->bf)
{
case 0:
{
(*T)->bf = -1;
smaller = 0;//左子树的高度本身没有变化,任然是当前结点右子树那么高
break;
}
case 1:
{
(*T)->bf = 0;
break;
}
case -1:
{
RightBalance(T);
break;
}
default:
break;
}
}
}
}
else if((*T)->val < key)
{
//在右子树中进行删除
if(!DeleteAVL(&(*T)->rchild, key, smaller))
{
return 0;
}
else
{
if(smaller)
{
switch ((*T)->bf)
{
case 0:
{
(*T)->bf = 1;
smaller = 0;//仍然与当前节点的左子树那么高
break;
}
case 1:
{
LeftBalance(T);
break;
}
case -1:
{
(*T)->bf = 0;
break;
}
default:
break;
}
}
}
}
else
{
//找到需要删除的节点
NODE *p = *T;
if(p->lchild && p->rchild)
{
//此节点有两个孩子,使用中序遍历的前驱来进行替换
NODE *q = p;
NODE *s = p->lchild;
while(s->rchild)
{
q = s;
s = s->rchild;
}
if(q != p)
{
p->val = s->val;
s->val = key;
if(!DeleteAVL(&(*T)->lchild, key, smaller))
{
return 0;
}
else
{
if(smaller)
{
switch ((*T)->bf)
{
case 0:
{
(*T)->bf = -1;
smaller = 0;//高度没有变化,仍然是右子树那么高
break;
}
case 1:
{
(*T)->bf = 0;
break;
}
case -1:
{
RightBalance(T);
break;
}
default:
break;
}
}
}
}
else
{
//左孩子没有右孩子
p->val = s->val;
p->lchild = s->lchild;
delete s;
s = NULL;
switch (p->bf)
{
case 0:
{
p->bf = -1;
smaller = 0;//高度并没有降低
break;
}
case 1:
{
p->bf = 0;
smaller = 0;//高度没有降低
break;
}
case -1:
{
smaller = 1;//高度降低
}
default:
break;
}
}
}
else
{
//此节点有1个或0个孩子
smaller = 1;
if((*T)->lchild)
{
//有左孩子,没有右孩子
*T = (*T)->lchild;
}
else if((*T)->rchild)
{
//有右孩子,没有左孩子
*T = (*T)->rchild;
}
else
{
//有0个孩子
*T = NULL;
}
delete p;
p = NULL;
}
return 1;
}
}
int main(int nArgs, char* pArg[])
{
int a[10] = {3, 2, 1, 4, 5, 6, 7, 10, 9, 8};
int taller = 0;
NODE *T = NULL;
for(int i = 0; i < 10; ++i)
{
InsertAVL(&T, a[i], taller);
}
int smaller = 0;
std::cout << DeleteAVL(&T, 2, smaller) << std::endl;
std::cout << DeleteAVL(&T, 3, smaller) << std::endl;
std::cout << DeleteAVL(&T, 7, smaller) << std::endl;
system("pause");
return 0;
}
#include <algorithm>
#include <vector>
//平衡二叉排序树
struct NODE
{
int val;
int bf;//平衡因子,当所有节点的平衡因子为-1、0、1时,此二叉排序树是平衡二叉排序树
NODE *lchild, *rchild;
};
void R_Rotate(NODE **p)
{
//右旋
NODE *q = (*p)->lchild;
(*p)->lchild = q->rchild;
q->rchild = *p;
*p = q;
}
void L_Rotate(NODE **p)
{
//左旋
NODE *q = (*p)->rchild;
(*p)->rchild = q->lchild;
q->lchild = *p;
*p = q;
}
void LeftBalance(NODE **T)
{
//对以指针T所指节点为根的二叉树做左平衡旋转处理
//此时T->bf > 1
//需考察T->lchild->bf与T->bf符号相同与不相同两种情况
NODE *L = (*T)->lchild;
switch(L->bf)
{
case 1:
{
//新插入的节点在T的左孩子的左子树上
//符号相同,直接右旋
L->bf = (*T)->bf = 0;
R_Rotate(T);
break;
}
case -1:
{
//新插入节点在T的左孩子的右子树上
//符号不同,需先对L左旋,调整L->bf与T->bf符号相同,再对T右旋
NODE *Lr = L->rchild;
switch (Lr->bf)
{
case 1:
{
L->bf = 0;
(*T)->bf = -1;
break;
}
case -1:
{
L->bf = 1;
(*T)->bf = 0;
break;
}
case 0:
{
(*T)->bf = L->bf = 0;
break;
}
default:
break;
}
Lr->bf = 0;
L_Rotate(&(*T)->lchild);
R_Rotate(T);
break;
}
case 0:
{
(*T)->bf = 1;
L->bf = -1;
R_Rotate(T);
break;
}
}
}
void RightBalance(NODE **T)
{
//对以指针T所指节点为根的二叉树做右平衡旋转处理
//此时T->bf < -1
//需考察T->lchild->bf与T->bf符号相同与不相同两种情况
NODE *R = (*T)->rchild;
switch (R->bf)
{
case 1:
{
//新插入的节点在T右子树的左孩子上
//R->bf与T->bf符号不同,需进行双旋转
NODE *rl = R->lchild;
switch (rl->bf)
{
case 1:
{
R->bf = -1;
(*T)->bf = 0;
break;
}
case -1:
{
R->bf = 0;
(*T)->bf = 1;
break;
}
case 0:
{
(*T)->bf = R->bf = 0;
break;
}
default:
break;
}
rl->bf = 0;
R_Rotate(&(*T)->rchild);
L_Rotate(T);
break;
}
case -1:
{
//新插入的节点在T右子树的右还是上
//R->bf与T->bf符号相同,直接旋转
(*T)->bf = R->bf = 0;
L_Rotate(T);
break;
}
case 0:
{
(*T)->bf = -1;
R->bf = 1;
L_Rotate(T);
break;
}
default:
break;
}
}
//taller用于记录树是否长高,即是否插入成功
//如果插入成功后,需递归回溯进行平衡调整,修改BF值
int InsertAVL(NODE **T, int key, int &taller)
{
if(!(*T))
{
*T = new NODE;
(*T)->val = key;
(*T)->bf = 0;
(*T)->lchild = (*T)->rchild = NULL;
taller = 1;
}
else
{
if(key == (*T)->val)
{
//树中已经有key了,插入失败
taller = 0;
return 0;
}
else if(key < (*T)->val)
{
if(!InsertAVL(&(*T)->lchild, key, taller))
{
//左子树中插入失败
return 0;
}
else
{
//左子树中插入成功
if(taller)
{
//树长高, 此时需修改T的BF
switch((*T)->bf)
{
//判断当前*T的BF值
case 0:
{
//原本左右子树等高,现因左子树增高而树增高
(*T)->bf = 1;
break;
}
case 1:
{
//原本左子树比右子树高,需作平衡处理
LeftBalance(T);
taller = 0;
break;
}
case -1:
{
//原本右子树比左子树高,现在左子树增高,左右子树等高
(*T)->bf = 0;
taller = 0;
break;
}
default:
break;
}
}
}
}
else
{
if(!InsertAVL(&(*T)->rchild, key, taller))
{
//插入失败
return false;
}
else
{
if(taller)
{
switch((*T)->bf)
{
case 0:
{
//原本等高,现在右子树比左子树高
(*T)->bf = -1;
break;
}
case 1:
{
//原本左子树高,现在等高
(*T)->bf = 0;
taller = 0;
break;
}
case -1:
{
//原本右子树高,现在右边插入,需调整
RightBalance(T);
taller = 0;
break;
}
default:
break;
}
}
}
}
}
}
//smaller用于标记树是否变矮
int DeleteAVL(NODE **T, int key, int &smaller)
{
if(!*T)
{
return 0;
}
else if((*T)->val > key)
{
//左子树中删除
if(!DeleteAVL(&(*T)->lchild, key, smaller))
{
return 0;
}
else
{
if(smaller)
{
//如果左子树高度降低了,需考察当前结点的高度,看是否进行旋转
switch ((*T)->bf)
{
case 0:
{
(*T)->bf = -1;
smaller = 0;//左子树的高度本身没有变化,任然是当前结点右子树那么高
break;
}
case 1:
{
(*T)->bf = 0;
break;
}
case -1:
{
RightBalance(T);
break;
}
default:
break;
}
}
}
}
else if((*T)->val < key)
{
//在右子树中进行删除
if(!DeleteAVL(&(*T)->rchild, key, smaller))
{
return 0;
}
else
{
if(smaller)
{
switch ((*T)->bf)
{
case 0:
{
(*T)->bf = 1;
smaller = 0;//仍然与当前节点的左子树那么高
break;
}
case 1:
{
LeftBalance(T);
break;
}
case -1:
{
(*T)->bf = 0;
break;
}
default:
break;
}
}
}
}
else
{
//找到需要删除的节点
NODE *p = *T;
if(p->lchild && p->rchild)
{
//此节点有两个孩子,使用中序遍历的前驱来进行替换
NODE *q = p;
NODE *s = p->lchild;
while(s->rchild)
{
q = s;
s = s->rchild;
}
if(q != p)
{
p->val = s->val;
s->val = key;
if(!DeleteAVL(&(*T)->lchild, key, smaller))
{
return 0;
}
else
{
if(smaller)
{
switch ((*T)->bf)
{
case 0:
{
(*T)->bf = -1;
smaller = 0;//高度没有变化,仍然是右子树那么高
break;
}
case 1:
{
(*T)->bf = 0;
break;
}
case -1:
{
RightBalance(T);
break;
}
default:
break;
}
}
}
}
else
{
//左孩子没有右孩子
p->val = s->val;
p->lchild = s->lchild;
delete s;
s = NULL;
switch (p->bf)
{
case 0:
{
p->bf = -1;
smaller = 0;//高度并没有降低
break;
}
case 1:
{
p->bf = 0;
smaller = 0;//高度没有降低
break;
}
case -1:
{
smaller = 1;//高度降低
}
default:
break;
}
}
}
else
{
//此节点有1个或0个孩子
smaller = 1;
if((*T)->lchild)
{
//有左孩子,没有右孩子
*T = (*T)->lchild;
}
else if((*T)->rchild)
{
//有右孩子,没有左孩子
*T = (*T)->rchild;
}
else
{
//有0个孩子
*T = NULL;
}
delete p;
p = NULL;
}
return 1;
}
}
int main(int nArgs, char* pArg[])
{
int a[10] = {3, 2, 1, 4, 5, 6, 7, 10, 9, 8};
int taller = 0;
NODE *T = NULL;
for(int i = 0; i < 10; ++i)
{
InsertAVL(&T, a[i], taller);
}
int smaller = 0;
std::cout << DeleteAVL(&T, 2, smaller) << std::endl;
std::cout << DeleteAVL(&T, 3, smaller) << std::endl;
std::cout << DeleteAVL(&T, 7, smaller) << std::endl;
system("pause");
return 0;
}