//author:yydrewdrew
#define ERROR -1
template <class T>
struct AVLTreeNode
{
T data;
int disheight;//height(right) - height(left)
AVLTreeNode<T> *left;
AVLTreeNode<T> *right;
AVLTreeNode<T> *parent;
};
template<class T>
class AVLTree
{
public:
AVLTree<T>(AVLTreeNode<T> *p = NULL):root(p){}
virtual ~AVLTree<T>();
AVLTree<T>(const AVLTree<T> &obj);
AVLTree<T> &operator = (const AVLTree<T> &obj);
public:
AVLTreeNode<T> *Serach(const T& t)const;
AVLTreeNode<T> *Insert(const T &t);
AVLTreeNode<T> *Delete(const T &t);
AVLTreeNode<T> *Successor(const T &t)const;
AVLTreeNode<T> *Predecessor(const T &t)const;
AVLTreeNode<T> *Min()const;
AVLTreeNode<T> *Max()const;
void Clear();
void TreeWalk()const;
void Swap(AVLTree &obj);
private:
void Clean()
{
root = NULL;
}
void Scan(AVLTreeNode<T> *p)const;
void Destory(AVLTreeNode<T> *p);
void InsertBalance(AVLTreeNode<T> *p);
void DeleteBalance(AVLTreeNode<T> *p);
void LLRotate(AVLTreeNode<T> *p);
void LRRotate(AVLTreeNode<T> *p);
void RLRotate(AVLTreeNode<T> *p);
void RRRotate(AVLTreeNode<T> *p);
void LRotate(AVLTreeNode<T> *p);
void RRotate(AVLTreeNode<T> *p);
void Copy(const AVLTreeNode<T> *const p);
private:
AVLTreeNode<T> *root;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Max()const
{
AVLTreeNode<T> *p = NULL;
AVLTreeNode<T> *p2 = NULL;
while (p != NULL)
{
p2 = p;
p = p->right;
}
return p2;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Min()const
{
AVLTreeNode<T> *p = root;
AVLTreeNode<T> *p2 = NULL;
while (p != NULL)
{
p2 = p;
p = p->left;
}
return p2;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTree<T> &AVLTree<T>::operator = (const AVLTree<T> &obj)
{
if (this != &obj)
{
Swap(AVLTree<T>(obj));
}
return *this;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTree<T>::AVLTree<T>(const AVLTree<T> &obj)
{
root = NULL;
Copy(obj.root);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::Copy(const AVLTreeNode<T> *const p)
{
if (p != NULL)
{
Copy(p->left);
Insert(p->data);
Copy(p->right);
}
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTree<T>::~AVLTree<T>()
{
Destory(root);
root = NULL;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::Clear()
{
Destory(root);
root = NULL;
return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::Destory(AVLTreeNode<T> *p)
{
if (p != NULL)
{
Destory(p->left);
Destory(p->right);
delete p;
p = NULL;
}
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::Swap(AVLTree<T> &obj)
{
std::swap(root,obj.root);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::TreeWalk()const
{
Scan(root);
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::Scan(AVLTreeNode<T> *p)const
{
if (p == NULL)
{
return;
}
Scan(p->left);
std::cout<<p->data<<std::endl;
Scan(p->right);
return;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Successor(const T &t)const
{
AVLTreeNode<T> *p = Serach(t);
if (p->right != NULL)
{
AVLTree<T> tem(p->right);
p = tem.Min();
tem.Clean();
return p;
}
else
{
AVLTreeNode<T> *p2 = p;
p = p->parent;
while (p != NULL && p2 == p->right)
{
p = p->parent;
}
return p;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Predecessor(const T &t)const
{
AVLTreeNode<T> * p = Serach(t);
if (p->left != NULL)
{
AVLTree<T> tem(p->left);
p = tem.Max();
tem.Clean();
return p;
}
else
{
AVLTreeNode<T> *p2 = p;
p = p->parent;
while (p != NULL && p2 == p->left)
{
p = p->parent;
}
return p;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Serach(const T &t)const
{
AVLTreeNode<T> *p = root;
while (p != NULL)
{
if (p->data > t)
{
p = p->left;
}
else if (p->data < t)
{
p = p->right;
}
else
{
break;
}
}
return p;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Insert(const T &t)
{
AVLTreeNode<T> *ptem = new AVLTreeNode<T>;
ptem->data = t;
ptem->left = NULL;
ptem->right = NULL;
ptem->disheight = 0;
AVLTreeNode<T> *p2 = NULL,*p = root;
while (p != NULL)
{
p2 = p;
if (p->data > t)
{
p = p->left;
}
else
{
p = p->right;
}
}
if (root == NULL)
{
root = ptem;
ptem->parent = NULL;
return root;
}
if (p2->data > t)
{
p2->left = ptem;
}
else
{
p2->right = ptem;
}
ptem->parent = p2;
InsertBalance(ptem);
return ptem;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
AVLTreeNode<T> *AVLTree<T>::Delete(const T &t)
{
AVLTreeNode<T> *p = Serach(t);
if (p == root || p == NULL)
{
root = NULL;
return p;
}
if (p->left == NULL && p->right == NULL)
{
if (p == p->parent->left)
{
p->parent->left = NULL;
}
else
{
p->parent->right = NULL;
}
DeleteBalance(p);
}
else if (p->left == NULL && p->right != NULL)
{
p->right->parent = p->parent;
if (p == p->parent->left)
{
p->parent->left = p->right;
}
else
{
p->parent->right = p->right;
}
DeleteBalance(p);
}
else if (p->left != NULL && p->right == NULL)
{
p->left->parent = p->parent;
if (p == p->parent->left)
{
p->parent->left = p->left;
}
else
{
p->parent->right = p->left;
}
DeleteBalance(p);
}
else
{
AVLTreeNode<T> *p2 = Successor(t);
if (p2 != root)
{
if (p2 == p2->parent->left)
{
p2->parent->left = p2->right;
}
else
{
p2->parent->right = p2->right;
}
}
AVLTreeNode<T> tem = *p;
*p = *p2;
p->parent = tem.parent;
p->left = tem.left;
p->right = tem.right;
DeleteBalance(p2);
*p2 = tem;
p = p2;
}
return p;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::InsertBalance(AVLTreeNode<T> *p)
{
AVLTreeNode<T> *p2 = NULL;
AVLTreeNode<T> *p3 = NULL;
while (p != root && p != NULL)
{
p3 = p2;
p2 = p;
p = p->parent;
int dis = p->disheight;
switch(dis)
{
case 0:
{
if (p2 == p->left)
{
p->disheight = -1;
}
else
{
p->disheight = 1;
}
break;
}
case 1:
{
if (p2 == p->left)
{
p->disheight = 0;
}
else
{
p->disheight = 2;
if (p3 == NULL)
{
throw ERROR;
}
if (p3 == p2->right)
{
RRRotate(p);
}
else
{
RLRotate(p);
}
}
p = root;
break;
}
case -1:
{
if (p2 == p->left)
{
p->disheight = -2;
if (p3 == NULL)
{
throw ERROR;
}
if (p3 == p->left)
{
LLRotate(p);
}
else
{
LRRotate(p);
}
}
else
{
p->disheight = 0;
}
p = root;
break;
}
default:
{
throw ERROR;
break;
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::LRotate(AVLTreeNode<T> *p)
{
AVLTreeNode<T> *p2 = p->right;
p2->parent = p->parent;
if (p->parent != NULL)
{
if (p == p->parent->left)
{
p->parent->left = p2;
}
else
{
p->parent->right = p2;
}
}
else
{
root = p2;
}
p->right = p2->left;
if (p2->left != NULL)
{
p2->left->parent = p;
}
p2->left = p;
p->parent = p2;
return;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::RRotate(AVLTreeNode<T> *p)
{
AVLTreeNode<T> *p2 = p->left;
p2->parent = p->parent;
if (p->parent != NULL)
{
if (p == p->parent->left)
{
p->parent->left = p2;
}
else
{
p->parent->right = p2;
}
}
else
{
root = p2;
}
p->left = p2->right;
if (p2->right != NULL)
{
p2->right->parent = p;
}
p2->right = p;
p->parent = p2;
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::DeleteBalance(AVLTreeNode<T> *p)
{
AVLTreeNode<T> *p2 = NULL;
while (p != NULL)
{
p2 = p->parent;
if (p->disheight == 0)
{
if (p == p2->left)
{
p2->disheight = 1;
}
else
{
p2->disheight = -1;
}
p = NULL;
}
else if (p->disheight == 1)
{
if (p == p2->left)
{
p2->disheight = 2;
AVLTreeNode<T> *p3 = p2->right;
switch(p3->disheight)
{
case 1:
{
p->disheight = 0;
p2->disheight = 0;
LRotate(p2);
p = p2->parent;
break;
}
case 0:
{
p3->disheight = -1;
p2->disheight = 1;
LRotate(p2);
p = NULL;
break;
}
case -1:
{
AVLTreeNode<T> *p4 = p3->left;
switch(p4->disheight)
{
case -1:
{
p2->disheight = 0;
p3->disheight = 1;
p4->disheight = 0;
RRotate(p3);
LRotate(p2);
p = p3->parent;
break;
}
case 0:
{
p2->disheight = -1;
p3->disheight = 0;
p4->disheight = 0;
RRotate(p3);
LRotate(p2);
p = p3->parent;
break;
}
case 1:
{
p2->disheight = 0;
p3->disheight = 0;
p4->disheight = 0;
RRotate(p3);
LRotate(p2);
p = p3->parent;
break;
}
default:
throw ERROR;
}
}
default:
throw ERROR;
}
}
else
{
p2->disheight = 0;
p = p->parent;
}
}
else if (p->disheight == -1)
{
if (p == p2->left)
{
p2->disheight = 0;
p = p->parent;
}
else
{
p2->disheight = -2;
AVLTreeNode<T> *p3 = p2->left;
switch(p3->disheight)
{
case 1:
{
p->disheight = 0;
p2->disheight = 0;
RRotate(p2);
p = p2->parent;
break;
}
case 0:
{
p3->disheight = -1;
p2->disheight = 1;
RRotate(p2);
p = NULL;
break;
}
case -1:
{
AVLTreeNode<T> *p4 = p3->left;
switch(p4->disheight)
{
case -1:
{
p2->disheight = 0;
p3->disheight = 1;
p4->disheight = 0;
LRotate(p3);
RRotate(p2);
p = p3->parent;
break;
}
case 0:
{
p2->disheight = -1;
p3->disheight = 0;
p4->disheight = 0;
LRotate(p3);
RRotate(p2);
p = p3->parent;
break;
}
case 1:
{
p2->disheight = 0;
p3->disheight = 0;
p4->disheight = 0;
LRotate(p3);
RRotate(p2);
p = p3->parent;
break;
}
default:
throw ERROR;
}
}
default:
throw ERROR;
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::RRRotate(AVLTreeNode<T> *p)
{
p->disheight = 0;
AVLTreeNode<T> *p2 = p->right;
p2->disheight = 0;
LRotate(p);
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::RLRotate(AVLTreeNode<T> *p)
{
AVLTreeNode<T> *p2 = p->right;
AVLTreeNode<T> *p3 = p2->left;
p->disheight = -1;
p2->disheight = 0;
p3->disheight = 0;
RRotate(p2);
LRotate(p);
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::LLRotate(AVLTreeNode<T> *p)
{
AVLTreeNode<T> *p2 = p->left;
p->disheight = 0;
p2->disheight = 0;
RRotate(p);
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void AVLTree<T>::LRRotate(AVLTreeNode<T> *p)
{
AVLTreeNode<T> *p2 = p->left;
AVLTreeNode<T> *p3 = p->left->right;
p->disheight = -1;
p2->disheight = 0;
p3->disheight = 0;
LRotate(p2);
RRotate(p);
return;
}