//
// main.cpp
// Data Structure TRY1
//
// Created by zr9558 on 6/7/13.
// Copyright (c) 2013 zr9558. All rights reserved.
//
// Data Structure C++, Weiss, P.136 AVL Trees
#include <iostream>
using namespace std;
template<typename Comparable>
class AvlTree{
public:
AvlTree() { root=NULL;}
AvlTree(const AvlTree &rhs) {operator=(rhs);}
~AvlTree() { makeEmpty();}
void printTree()const
{
PrintTree(root,0);
cout<<endl;
}
void printTreeInOrder()const
{
PrintTreeInOrder(root);
cout<<endl;
}
void makeEmpty() { makeEmpty(root);}
void insert(const Comparable &x)
{
insert(x,root);
}
const AvlTree &operator=(const AvlTree &rhs)
{
if(this!=&rhs)
{
makeEmpty();
root=clone(rhs.root);
}
return *this;
}
private:
struct AvlNode
{
Comparable element;
AvlNode *left;
AvlNode *right;
int height;
AvlNode(const Comparable & theElement, AvlNode *lt, AvlNode *rt,int h=0)
: element(theElement), left(lt), right(rt), height(h){}
};
int height( AvlNode *t)const
{
return t==NULL ? -1: t->height;
}
AvlNode * root;
void makeEmpty( AvlNode *t)const
{
if( t!=NULL)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t=NULL;
}
void PrintTree( AvlNode * t,int level) const
{
if( t!=NULL)
{
PrintTree( t->right,level+1);
for(int i=0; i<4*level; ++i)
cout<<" ";
cout<<t->element<<endl;
PrintTree( t->left, level+1);
}
}
void PrintTreeInOrder( AvlNode *t)const
{
if( t!=NULL)
{
PrintTreeInOrder(t->left);
cout<<t->element<<" ";
PrintTreeInOrder(t->right);
}
}
AvlNode * clone( AvlNode *t)const
{
if( t==NULL)returnNULL;
returnnew AvlNode(t->element, clone(t->left), clone(t->right),t->height);
}
void rotateWithLeftChild( AvlNode * &k2)
{
AvlNode *k1=k2->left;
k2->left=k1->right;
k1->right=k2;
k2->height=max(height(k2->left),height(k2->right))+1;
k1->height=max(height(k1->left),height(k2))+1;
k2=k1;
}
void rotateWithRightChild( AvlNode * &k2)
{
AvlNode *k1=k2->right;
k2->right=k1->left;
k1->left=k2;
k2->height=max(height(k2->left),height(k2->right))+1;
k1->height=max(height(k1->right),height(k2))+1;
k2=k1;
}
void doubleWithLeftChild( AvlNode * &k3)
{
rotateWithRightChild(k3->left);
rotateWithLeftChild(k3);
}
void doubleWithRightChild( AvlNode * &k3)
{
rotateWithLeftChild(k3->right);
rotateWithRightChild(k3);
}
void insert(const Comparable &x, AvlNode * &t)
{
if( t==NULL)
t=new AvlNode(x,NULL,NULL);
elseif( x<t->element)
{
insert(x,t->left);
if( height(t->left)-height(t->right)==2)
{
if( x<t->left->element)
rotateWithLeftChild(t);
else
doubleWithLeftChild(t);
}
}
elseif( t->element<x)
{
insert(x,t->right);
if( height(t->right)-height(t->left)==2)
{
if( t->right->element<x)
rotateWithRightChild(t);
else
doubleWithRightChild(t);
}
}
else ;// Duplicate; do nothing;
t->height=max(height(t->left), height(t->right))+1;
}
};
int main()
{
AvlTree<int> T;
for(int i=20; i<60; ++i)
T.insert(i);
T.printTreeInOrder();
T.printTree();
return 0;
}