平衡二叉树(AVL)
Feature
AVL is a kind of highly balanced binary search tree. "Highly balanced" means that every node, its difference between the depth of its left child tree and that of its right child tree is no more than \(1\). We can define this as Balance Factor. And the value of BF is constrained by \(-1, 0, 1\). Keep the balance of the AVL is the most important thing when we do all the operations on the AVL such like insert, delete and etc.
The good way to keep its balance is "spin".
Four Condition Ruin The Balance
Assume that p is the first node whose BF is wrong along the way that is originated from the inserted node up the tree. And there are four possible way to ruin p's balance:
- the left child's left child tree.
- the left child's right child tree.
- the right child's left child tree.
- the right child's right child tree.
Two Kinds Of Spin To Fix BF
- Single Rotation: this method will suit the situation of the first and the forth imbalanced condition.
- Double Rotation: suit the rest of the imbalanced situation.
Here's one way to realize it, but it keep BF in the node structure which cause it's too hard to achieve the remove operation.
typedef enum {RH= -1, EH= 0, LH= 1} BF;
typedef struct Node{
int pry;
int clt;
int bf;
Node *lc, *rc;
bool operator < (const Node &a) const{
return pry< a.pry;
}
}Node, *Tree;
void L_Rotate(Tree *T)
{
Tree R= (*T)->rc;
(*T)->rc= R->lc;
R->lc= *T;
*T= R;
}
void R_Rotate(Tree *T)
{
Tree L= (*T)->lc;
(*T)->lc= L->rc;
L->rc= *T;
*T= L;
}
void LeftBalance(Tree *T)
{
Tree L, Lr;
L= (*T)->lc;
switch(L->bf){
case LH:
(*T)->bf= L->bf= EH;
R_Rotate(T);
break;
case RH:
Lr= L->rc;
switch(Lr->bf){
case LH:
(*T)->bf= RH;
L->bf= EH;
break;
case EH:
(*T)->bf= L->bf= EH;
break;
case RH:
(*T)->bf= EH;
L->bf= LH;
break;
default:
break;
}
Lr->bf= EH;
L_Rotate(&((*T)->lc));
R_Rotate(T);
break;
default:
break;
}
}
void RightBalance(Tree *T)
{
Tree R, Rl;
R= (*T)->rc;
switch(R->bf){
case LH:
Rl= R->lc;
switch(Rl->bf){
case LH:
(*T)->bf= EH;
R->bf= RH;
break;
case EH:
(*T)->bf= R->bf= EH;
break;
case RH:
(*T)->bf= LH;
R->bf= EH;
break;
default:
break;
}
Rl->bf= EH;
R_Rotate(&((*T)->rc));
L_Rotate(T);
break;
case RH:
(*T)->bf= R->bf= EH;
L_Rotate(T);
break;
default:
break;
}
}
bool InsertAVL(Tree *T, int pry, bool &taller)
{
if (!(*T)){
*T= (Tree)malloc(sizeof(Node));
(*T)->pry= pry;
(*T)->lc= (*T)->rc= NULL;
(*T)->bf= EH;
taller= true;
}
else{
if (pry== (*T)->pry){
taller= false;
return false;
}
if (pry< (*T)->pry){
if (!InsertAVL(&((*T)->lc), pry, taller)) {
return false;
}
if (taller){
if (LH== (*T)->bf){
LeftBalance(T);
taller= false;
}
else if (EH== (*T)->bf){
(*T)->bf= LH;
taller= true;
}
else if (RH== (*T)->bf){
(*T)->bf= EH;
taller= false;
}
}
}
else{
if (!InsertAVL(&((*T)->rc), pry, taller)){
return false;
}
if (taller){
if (LH== (*T)->bf){
(*T)->bf= EH;
taller =false;
}
else if (EH== (*T)->bf){
(*T)->bf= RH;
taller= true;
}
else if (RH== (*T)->bf){
RightBalance(T);
taller= false;
}
}
}
}
return true;
}
OJ Practise
POJ 3481
/*fxxk u, AVL, why so long? Ugly like a bullshit*/
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxk= 1e6;
const int maxp= 1e7;
class AvlTree{
struct Node{
int clt;
int pry;
Node *lc, *rc;
int h;
Node(int clt, int pry) : clt(clt), pry(pry), lc(NULL), rc(NULL), h(1) {}
~Node()
{
if (lc){
delete lc;
}
if (rc){
delete rc;
}
}
};
void UpdateHeight(Node *p)
{
p->h= max(GetHeight(p->lc), GetHeight(p->rc))+1;
}
int GetHeight(Node *p)
{
if (!p){
return 0;
}
return p->h;
}
Node* LeftRotate(Node *rt)
{
Node *R= rt->rc;
rt->rc= R->lc;
R->lc= rt;
UpdateHeight(rt);
UpdateHeight(R);
return R;
}
Node* RightRotate(Node *rt)
{
Node *L= rt->lc;
rt->lc= L->rc;
L->rc= rt;
UpdateHeight(rt);
UpdateHeight(L);
return L;
}
int GetBF(Node *p)
{
if (!p){
return 0;
}
return GetHeight(p->lc)-GetHeight(p->rc);
}
Node* Balance(Node *p)
{
if (!p){
return p;
}
UpdateHeight(p);
int bf= GetBF(p), bf1;
if (bf> 1){
bf1= GetBF(p->lc);
if(bf1>= 0){
return RightRotate(p);
}
else if (bf1< 0){
p->lc= LeftRotate(p->lc);
return RightRotate(p);
}
}
else if (bf< -1){
bf1= GetBF(p->rc);
if (bf1<= 0){
return LeftRotate(p);
}
else if (bf1> 0){
p->rc= RightRotate(p->rc);
return LeftRotate(p);
}
}
return p;
}
Node* Insert(Node *p, int clt, int pry)
{
if (!p){
return new Node(clt, pry);
}
if (pry< p->pry){
p->lc= Insert(p->lc, clt, pry);
}
else{
p->rc= Insert(p->rc, clt, pry);
}
return Balance(p);
}
Node* MinValueNode(Node *p)
{
if (!p){
return p;
}
Node *cur= p;
while (cur->lc){
cur= cur->lc;
}
return cur;
}
Node* MaxValueNode(Node *p)
{
if (!p){
return 0;
}
Node *cur= p;
while (cur->rc){
cur= cur->rc;
}
return cur;
}
Node* Delete(Node *r, int pry)
{
if (!r){
return r;
}
if (pry< r->pry){
r->lc= Delete(r->lc, pry);
}
else if (pry> r->pry){
r->rc= Delete(r->rc, pry);
}
else{
if (!r->rc || !r->lc){
Node *tmp= r->lc?r->lc:r->rc;
if (!tmp){
tmp= r;
r= NULL;
}
else{
*r= *tmp;
}
delete tmp;
tmp= NULL;
}
else{
Node *tmp= MinValueNode(r->rc);
r->pry= tmp->pry;
r->rc= Delete(r->rc, tmp->pry);
}
}
return Balance(r);
}
void PreOrder(Node *r)
{
if (NULL!= r){
PreOrder(r->lc);
printf("%d ", r->pry);
PreOrder(r->rc);
}
}
void FreeNode(Node *r)
{
if (!r){
return;
}
if (r->rc){
FreeNode(r->rc);
}
if (r->lc){
FreeNode(r->lc);
}
delete r;
}
public:
void Solve()
{
int odr, k, p;
Node *root= NULL;
while(EOF!= scanf("%d", &odr)){
if (!odr){
break;
}
if (1== odr){
scanf("%d %d", &k, &p);
root= Insert(root, k, p);
}
else if(2== odr){
Node *mx= MaxValueNode(root);
if (!mx){
printf("0\n");
}
else{
printf("%d\n", mx->clt);
root= Delete(root, mx->pry);
}
}
else if (3== odr){
Node *mn= MinValueNode(root);
if (!mn){
printf("0\n");
}
else{
printf("%d\n", mn->clt);
root= Delete(root, mn->pry);
}
}
}
}
};
int main()
{
AvlTree ans;
ans.Solve();
return 0;
}

浙公网安备 33010602011771号