#include <iostream>
#include <stack>
#include <time.h>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
//class AVL tree
class CAvlTree{
private:
struct node{
node *left,*right,*parent;
char value;
int height;
node():left(NULL),right(NULL),parent(NULL),value(0),height(1){};
};
node *root;
inline int getheight(node *r){
if(r==NULL) return 0;
return r->height;
}
inline int getbl(node *r){
if(r==NULL) return 0;
return getheight(r->left)-getheight(r->right);
}
node* Retate_L(node *r)
{
node *r1;
r1=r->left;
r1->parent=r->parent;
r->left=r1->right;
if(r1->right!=NULL) r1->right->parent=r;
r->parent=r1;
r1->right=r;
r->height=max(getheight(r->left),getheight(r->right))+1;
r1->height=max(getheight(r1->left),getheight(r1->right))+1;
return r1;
}
node* Retate_R(node *r)
{
node *r1;
r1=r->right;
r1->parent=r->parent;
r->right=r1->left;
if(r1->left!=NULL) r1->left->parent=r;
r->parent=r1;
r1->left=r;
r->height=max(getheight(r->left),getheight(r->right))+1;
r1->height=max(getheight(r1->left),getheight(r1->right))+1;
return r1;
}
node* Retate_LR(node *r)
{
r->right=Retate_L(r->right);
return Retate_R(r);
}
node* Retate_RL(node *r)
{
r->left=Retate_R(r->left);
return Retate_L(r);
}
node* Adjust(node *r,node *q){
bool bb=false;
node *fq;
while(q!=NULL){
if(q==r) bb=true;
fq=q->parent;
q->height=max(getheight(q->left),getheight(q->right))+1;
if(getbl(q)==2){
if(getbl(q->left)>=0){ //L
if(q==r) r=Retate_L(q);
else if(q==fq->left) fq->left=Retate_L(q);
else fq->right=Retate_L(q);
}
else if(getbl(q->left)==-1){ //RL
if(q==r) r=Retate_RL(q);
else if(q==fq->left) fq->left=Retate_RL(q);
else fq->right=Retate_RL(q);
}
}
else if(getbl(q)==-2){
if(getbl(q->right)<=0){ //R
if(q==r) r=Retate_R(q);
else if(q==fq->left) fq->left=Retate_R(q);
else fq->right=Retate_R(q);
}
else if(getbl(q->right)==1){ //LR
if(q==r) r=Retate_LR(q);
else if(q==fq->left) fq->left=Retate_LR(q);
else fq->right=Retate_LR(q);
}
}
if(bb) break;
q=fq;
}
return r;
}
node* Delete(node *r,char ch){
if(r==NULL) return NULL;
node *p=r;
//search ch
while(p!=NULL&&ch!=p->value){
if(ch<p->value) p=p->left;
else if(ch>p->value) p=p->right;
}
//not searched
if(p==NULL) return r;
//replace the node and find the last need delete node p
while(p->left!=NULL){
node *q=p->left;
while(q->right!=NULL) q=q->right;
p->value=q->value;
p=q;
}
//delete p
node *fp;
if(p==r){
fp=NULL;
r=p->right;
if(p->right!=NULL) p->right->parent=p->parent;
delete p;
}
else{
fp=p->parent;
if(p->parent->left==p) p->parent->left=p->right;
else p->parent->right=p->right;
if(p->right!=NULL) p->right->parent=p->parent;
delete p;
}
//adjust height and retate from q to r;
r=Adjust(r,fp);
return r;
}
node* Insert(node *r,char ch){
//new node s
node *s=new node;
s->value=ch;
//insert node
if(r==NULL) return s;
node *p=r,*fp;
while(p!=NULL){
fp=p;
if(ch<p->value) p=p->left;
else p=p->right;
}
if(ch<fp->value) fp->left=s;
else fp->right=s;
s->parent=fp;
//adjust height and retate from q to r;
r=Adjust(r,fp);
return r;
}
public:
CAvlTree(){
root=NULL;
}
~CAvlTree(){
Clear();
}
void Insert(char ch){
root=Insert(root,ch);
}
void Delete(char ch){
root=Delete(root,ch);
}
void Clear(){
while(root!=NULL){
root=Delete(root,root->value);
}
}
friend class CAvlTree_Test;
};
//class test AVL tree
class CAvlTree_Test{
private:
CAvlTree *t;
typedef CAvlTree::node node;
int depth(node *r){
if(r==NULL) return 0;
int ld,rd;
ld=depth(r->left);
rd=depth(r->right);
return max(ld,rd)+1;
}
void PrintSortedTree(){
stack<node*> st;
node *p=t->root;
char lastch=0;
while(p!=NULL||!st.empty()){
if(p!=NULL){
st.push(p);
p=p->left;
}
else{
p=st.top();st.pop();
cout<<p->value<<"("<<depth(p->left)<<","<<depth(p->right)<<") ";
p=p->right;
}
}
}
bool CheckAvl(){
stack<node*> st;
node *p=t->root;
char lastch=0;
while(p!=NULL||!st.empty()){
if(p!=NULL){
st.push(p);
p=p->left;
}
else{
p=st.top();st.pop();
if(depth(p)!=p->height) {
cout<<"("<<p->value<<")"<<depth(p)<<"!="<<p->height<<endl;
return false;
}
if(abs(t->getheight(p->left)-t->getheight(p->right))>=2){
cout<<"("<<p->value<<")"<<t->getheight(p->left)<<"-"<<t->getheight(p->right)<<">=2"<<endl;
return false;
}
if(p->left!=NULL&&p->left->parent!=p){
cout<<"("<<p->value<<")"<<p->left->parent<<"!="<<p<<endl;
return false;
}
if(p->right!=NULL&&p->right->parent!=p){
cout<<"("<<p->value<<")"<<p->right->parent<<"!="<<p<<endl;
return false;
}
if(lastch>p->value){
cout<<"("<<p->value<<")lastch="<<lastch<<endl;
return false;
}
p=p->right;
}
}
return true;
}
void BeginTest(){
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
int i,j,n,m;
cin>>n;
for(i=0;i<n;i++){
t=new CAvlTree;
cout<<"insert["<<i<<"]:"<<endl;
cin>>m;
for(j=0;j<m;j++){
cout<<j<<"->";
char ch;
cin>>ch;
t->Insert(ch);
cout<<"insert("<<ch<<")->";
if(CheckAvl()) cout<<"ok"<<endl;
else cout<<"no"<<endl;
PrintSortedTree();cout<<endl;
}
cout<<"delete["<<i<<":"<<endl;
for(j=0;j<m;j++){
cout<<j<<"->";
char ch;
cin>>ch;
t->Delete(ch);
cout<<"Delete("<<ch<<")->";
if(CheckAvl()) cout<<"ok"<<endl;
else cout<<"no"<<endl;
PrintSortedTree();cout<<endl;
}
delete t;
}
}
void RandInitData(){
freopen("test.in","w",stdout);
srand(time(NULL));
const int max_test=5;
const int max_num=200;
const char max_chr='z';
const char min_chr='0';
char chr[max_num];
int n=max_test,m;
int i=0,j=0;
cout<<n*3<<endl;
for(i=0;i<n;i++){
m=rand()%max_num+1;
for(j=0;j<m;j++) chr[j]=rand()%(max_chr-min_chr+1)+min_chr;
//insert data
cout<<m<<" ";
for(j=0;j<m;j++) cout<<chr[j];
cout<<endl;
//delete data
cout<<m<<" ";
for(j=0;j<m;j++) cout<<chr[j];
cout<<endl;
//insert data
cout<<m<<" ";
for(j=0;j<m;j++) cout<<chr[j];
cout<<endl;
//delete data
cout<<m<<" ";
for(j=m-1;j>=0;j--) cout<<chr[j];
cout<<endl;
//insert data
cout<<m<<" ";
for(j=0;j<m;j++) cout<<chr[j];
cout<<endl;
//delete data
cout<<m<<" ";
for(j=0;j<m;j++) cout<<chr[rand()%m];
cout<<endl;
}
fclose(stdout);
freopen("CON","w",stdout);
}
public:
void run(){
RandInitData();
BeginTest();
}
};
int main(){
CAvlTree_Test * tt= new CAvlTree_Test;
tt->run();
delete tt;
return 0;
}