//
// main.cpp
// Data Structure TRY1
//
// Created by zr9558 on 6/7/13.
// Copyright (c) 2013 zr9558. All rights reserved.
//
// Data Structures C++ Weiss: P.521 SplayTree
#include<iostream>
using namespace std;
#include<vector>
#include<math.h>
template<typename Comparable>
class SplayTree
{
public:
SplayTree()
{
nullNode= new BinaryNode;
nullNode->left=nullNode->right=nullNode;
root=nullNode;
}
SplayTree( const SplayTree &rhs)
{
nullNode= new BinaryNode;
nullNode->left=nullNode->right=nullNode;
root=clone(rhs.root);
}
const SplayTree & operator=( const SplayTree &rhs)
{
if( this!=&rhs)
{
makeEmpty();
nullNode= new BinaryNode;
nullNode->left=nullNode->right=nullNode;
root=clone(rhs.root);
}
return *this;
}
~SplayTree()
{
makeEmpty();
delete nullNode;
}
/**
* Find the largest item in the tree.
* Not the most efficient implementation (uses two passes), but has correct
* amortized behavior.
* A good alternative is to first call find with parameter
* larger than any item in the tree, then call findMax.
* Return the largest item or throw UnderflowException if empty.
*/
const Comparable & findMax()
{
BinaryNode *ptr=root;
while( ptr->right!=nullNode)
ptr=ptr->right;
splay(ptr->element, root);
return ptr->element;
}
/**
* Find the smallest item in the tree.
* Not the most efficient implementation (uses two passes), but has correct
* amortized behavior.
* A good alternative is to first call find with parameter
* smaller than any item in the tree, then call findMin.
* Return the smallest item or throw UnderflowException if empty.
*/
const Comparable & findMin()
{
BinaryNode *ptr=root;
while( ptr->left!=nullNode)
ptr=ptr->left;
splay(ptr->element,root);
return ptr->element;
}
bool contains( const Comparable &x) const
{
return contains(x,root);
}
bool isEmpty() const
{
return root==nullNode;
}
void printTree() const
{
printtree(root);
}
void printTree1() const
{
printtree1(root,0);
}
void makeEmpty()
{
/******************************
* Comment this out, because it is prone to excessive
* recursion on degenerate trees. Use alternate algorithm.
reclaimMemory( root );
root = nullNode;
*******************************/
while( !isEmpty())
{
findMax(); // Splay max item to root
remove(root->element);
}
}
void insert( const Comparable &x);
void remove( const Comparable &x);
private:
struct BinaryNode
{
Comparable element;
BinaryNode *left, *right;
BinaryNode():left(NULL), right(NULL){}
BinaryNode( const Comparable &theElement, BinaryNode *lt, BinaryNode *rt)
: element(theElement), left(lt), right(rt){}
};
BinaryNode *root;
BinaryNode *nullNode;
void rotateWithLeftChild( BinaryNode *&k2)
{
BinaryNode *k1=k2->left;
k2->left=k1->right;
k1->right=k2;
k2=k1;
}
void rotateWithRightChild( BinaryNode *&k2)
{
BinaryNode *k1=k2->right;
k2->right=k1->left;
k1->left=k2;
k2=k1;
}
void splay( const Comparable &x, BinaryNode * &t)
{
BinaryNode *leftTreeMax, *rightTreeMin;
static BinaryNode header;
header.left=header.right=nullNode;
leftTreeMax=rightTreeMin=&header;
nullNode->element=x; // Guarantee a match
for( ; ; )
{
if( x<t->element)
{
if( x<t->left->element)
rotateWithLeftChild(t);
if( t->left==nullNode)
break;
// Link Right
rightTreeMin->left=t;
rightTreeMin=t;
t=t->left;
}
else if( x>t->element)
{
if( x>t->right->element)
rotateWithRightChild(t);
if( t->right==nullNode)
break;
// Link Left
leftTreeMax->right=t;
leftTreeMax=t;
t=t->right;
}
else break;
}
leftTreeMax->right=t->left;
rightTreeMin->left=t->right;
t->left=header.right;
t->right=header.left;
}
BinaryNode *clone( BinaryNode *t)
{
if( t==t->left) return nullNode; // Cannot test against nullNode;
return new BinaryNode(t->element, clone(t->left), clone(t->right));
}
bool contains( const Comparable &x, BinaryNode *t) const
{
if( t==t->left) return false;
else if( x<t->element) return contains(x,t->left);
else if( x>t->element) return contains(x,t->right);
else return true;
}
void printtree( BinaryNode *t) const
{
if( t!=nullNode)
{
printtree(t->left);
cout<<t->element<<endl;
printtree(t->right);
}
}
void printtree1( BinaryNode *t, int level) const
{
if(t!=nullNode)
{
printtree1( t->right, level+1);
for( int i=0; i<4*level; ++i)
cout<<" ";
cout<<t->element<<endl;
printtree1( t->left, level+1);
}
}
};
template<typename Comparable>
void SplayTree<Comparable>::insert( const Comparable &x)
{
static BinaryNode *newNode=NULL;
if( newNode==NULL)
newNode=new BinaryNode;
newNode->element=x;
if( root==nullNode)
{
newNode->left=newNode->right=nullNode;
root=newNode;
}
else
{
splay(x,root);
if( x<root->element)
{
newNode->left=root->left;
newNode->right=root;
root->left=nullNode;
root=newNode;
}
else if( x>root->element)
{
newNode->right=root->right;
newNode->left=root;
root->right=nullNode;
root=newNode;
}
else return;
}
newNode=NULL; // so next insert will call new, since newNode is a static variable.
}
template<typename Comparable>
void SplayTree<Comparable>::remove(const Comparable &x)
{
BinaryNode *newTree;
// If x is found, it will be at the root
splay(x,root);
if( root->element!=x)
return; // Item not found, do nothing
if( root->left==nullNode)
newTree=root->right;
else
{
//Find the maximum in the left subtree
// Splay it to the root; and then attach right child
newTree=root->left;
splay(x,newTree);
newTree->right=root->right;
}
delete root;
root=newTree;
}
int main()
{
SplayTree<int> T1;
for( int i=0; i<30; ++i)
T1.insert(rand()%100);
SplayTree<int> T=T1;
T.printTree1();
T.printTree();
int x;
while( cin>>x)
{
if( T.contains(x)) { T.remove(x); T.printTree1();}
else cout<<"no contain"<<endl;
}
return 0;
}