Pagini recente » Monitorul de evaluare | Istoria paginii runda/oji201811/clasament | Cod sursa (job #2189978) | Cod sursa (job #436290) | Cod sursa (job #1182517)
#include <cstdio>
#include <set>
#include <cstdlib>
#include <ctime>
using namespace std;
#ifndef RED_BLACK_TREE_H_
#define RED_BLACK_TREE_H_
#include <iostream> // For NULL
// Red-black tree class
//
// CONSTRUCTION: with negative infinity object also
// used to signal failed finds
//
// ******************PUBLIC OPERATIONS*********************
// void insert( x ) --> Insert x
// void remove( x ) --> Remove x (unimplemented)
// Comparable find( x ) --> Return item that matches x
// Comparable findMin( ) --> Return smallest item
// Comparable findMax( ) --> Return largest item
// boolean isEmpty( ) --> Return true if empty; else false
// void makeEmpty( ) --> Remove all items
// void printTree( ) --> Print tree in sorted order
// Node and forward declaration because g++ does
// not understand nested classes.
template <class Comparable>
class RedBlackTree;
template <class Comparable>
class RedBlackNode
{
Comparable element;
RedBlackNode *left;
RedBlackNode *right;
int color;
// c = 1 should be c = RedBlackTree<Comparable>::BLACK
// But Visual 5.0 does not comprehend it.
RedBlackNode( const Comparable & theElement = Comparable( ),
RedBlackNode *lt = NULL, RedBlackNode *rt = NULL,
int c = 1 )
: element( theElement ), left( lt ), right( rt ), color( c ) { }
friend class RedBlackTree<Comparable>;
};
template <class Comparable>
class RedBlackTree
{
public:
explicit RedBlackTree( const Comparable & negInf );
RedBlackTree( const RedBlackTree & rhs );
~RedBlackTree( );
const Comparable & findMin( ) const;
const Comparable & findMax( ) const;
const Comparable & find( const Comparable & x ) const;
bool isEmpty( ) const;
void printTree( ) const;
void makeEmpty( );
void insert( const Comparable & x );
void remove( const Comparable & x );
enum { RED, BLACK };
const RedBlackTree & operator=( const RedBlackTree & rhs );
private:
RedBlackNode<Comparable> *header; // The tree header (contains negInf)
const Comparable ITEM_NOT_FOUND;
RedBlackNode<Comparable> *nullNode;
// Used in insert routine and its helpers (logically static)
RedBlackNode<Comparable> *current;
RedBlackNode<Comparable> *parent;
RedBlackNode<Comparable> *grand;
RedBlackNode<Comparable> *great;
// Usual recursive stuff
void reclaimMemory( RedBlackNode<Comparable> *t ) const;
void printTree( RedBlackNode<Comparable> *t ) const;
RedBlackNode<Comparable> * clone( RedBlackNode<Comparable> * t ) const;
// Red-black tree manipulations
void handleReorient( const Comparable & item );
RedBlackNode<Comparable> * rotate( const Comparable & item,
RedBlackNode<Comparable> *parent ) const;
void rotateWithLeftChild( RedBlackNode<Comparable> * & k2 ) const;
void rotateWithRightChild( RedBlackNode<Comparable> * & k1 ) const;
};
#endif
/**
* Construct the tree.
* negInf is a value less than or equal to all others.
* It is also used as ITEM_NOT_FOUND.
*/
template <class Comparable>
RedBlackTree<Comparable>::RedBlackTree( const Comparable & negInf )
: ITEM_NOT_FOUND( negInf )
{
nullNode = new RedBlackNode<Comparable>;
nullNode->left = nullNode->right = nullNode;
header = new RedBlackNode<Comparable>( negInf );
header->left = header->right = nullNode;
}
/**
* Copy constructor.
*/
template <class Comparable>
RedBlackTree<Comparable>::RedBlackTree( const RedBlackTree<Comparable> & rhs )
: ITEM_NOT_FOUND( rhs.ITEM_NOT_FOUND )
{
nullNode = new RedBlackNode<Comparable>;
nullNode->left = nullNode->right = nullNode;
header = new RedBlackNode<Comparable>( ITEM_NOT_FOUND );
header->left = header->right = nullNode;
*this = rhs;
}
/**
* Destroy the tree.
*/
template <class Comparable>
RedBlackTree<Comparable>::~RedBlackTree( )
{
makeEmpty( );
delete nullNode;
delete header;
}
/**
* Insert item x into the tree. Does nothing if x already present.
*/
template <class Comparable>
void RedBlackTree<Comparable>::insert( const Comparable & x )
{
current = parent = grand = header;
nullNode->element = x;
while( current->element != x )
{
great = grand; grand = parent; parent = current;
current = x < current->element ? current->left : current->right;
// Check if two red children; fix if so
if( current->left->color == RED && current->right->color == RED )
handleReorient( x );
}
// Insertion fails if already present
if( current != nullNode )
return;
current = new RedBlackNode<Comparable>( x, nullNode, nullNode );
// Attach to parent
if( x < parent->element )
parent->left = current;
else
parent->right = current;
handleReorient( x );
}
/**
* Remove item x from the tree.
* Not implemented in this version.
*/
template <class Comparable>
void RedBlackTree<Comparable>::remove( const Comparable & x )
{
cout << "Sorry, remove unimplemented; " << x <<
" still present" << endl;
}
/**
* Find the smallest item the tree.
* Return the smallest item or ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & RedBlackTree<Comparable>::findMin( ) const
{
if( isEmpty( ) )
return ITEM_NOT_FOUND;
RedBlackNode<Comparable> *itr = header->right;
while( itr->left != nullNode )
itr = itr->left;
return itr->element;
}
/**
* Find the largest item in the tree.
* Return the largest item or ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & RedBlackTree<Comparable>::findMax( ) const
{
if( isEmpty( ) )
return ITEM_NOT_FOUND;
RedBlackNode<Comparable> *itr = header->right;
while( itr->right != nullNode )
itr = itr->right;
return itr->element;
}
/**
* Find item x in the tree.
* Return the matching item or ITEM_NOT_FOUND if not found.
*/
template <class Comparable>
const Comparable & RedBlackTree<Comparable>::find( const Comparable & x ) const
{
nullNode->element = x;
RedBlackNode<Comparable> *curr = header->right;
for( ; ; )
{
if( x < curr->element )
curr = curr->left;
else if( curr->element < x )
curr = curr->right;
else if( curr != nullNode )
return curr->element;
else
return ITEM_NOT_FOUND;
}
}
/**
* Make the tree logically empty.
*/
template <class Comparable>
void RedBlackTree<Comparable>::makeEmpty( )
{
reclaimMemory( header->right );
header->right = nullNode;
}
/**
* Test if the tree is logically empty.
* Return true if empty, false otherwise.
*/
template <class Comparable>
bool RedBlackTree<Comparable>::isEmpty( ) const
{
return header->right == nullNode;
}
/**
* Print the tree contents in sorted order.
*/
template <class Comparable>
void RedBlackTree<Comparable>::printTree( ) const
{
if( header->right == nullNode )
cout << "Empty tree" << endl;
else
printTree( header->right );
}
/**
* Deep copy.
*/
template <class Comparable>
const RedBlackTree<Comparable> &
RedBlackTree<Comparable>::operator=( const RedBlackTree<Comparable> & rhs )
{
if( this != &rhs )
{
makeEmpty( );
header->right = clone( rhs.header->right );
}
return *this;
}
/**
* Internal method to print a subtree t in sorted order.
*/
template <class Comparable>
void RedBlackTree<Comparable>::printTree( RedBlackNode<Comparable> *t ) const
{
if( t != t->left )
{
printTree( t->left );
cout << t->element << endl;
printTree( t->right );
}
}
/**
* Internal method to clone subtree.
*/
template <class Comparable>
RedBlackNode<Comparable> *
RedBlackTree<Comparable>::clone( RedBlackNode<Comparable> * t ) const
{
if( t == t->left ) // Cannot test against nullNode!!!
return nullNode;
else
return new RedBlackNode<Comparable>( t->element, clone( t->left ),
clone( t->right ), t->color );
}
/**
* Internal routine that is called during an insertion
* if a node has two red children. Performs flip
* and rotatons.
* item is the item being inserted.
*/
template <class Comparable>
void RedBlackTree<Comparable>::handleReorient( const Comparable & item )
{
// Do the color flip
current->color = RED;
current->left->color = BLACK;
current->right->color = BLACK;
if( parent->color == RED ) // Have to rotate
{
grand->color = RED;
if( item < grand->element != item < parent->element )
parent = rotate( item, grand ); // Start dbl rotate
current = rotate( item, great );
current->color = BLACK;
}
header->right->color = BLACK; // Make root black
}
/**
* Internal routine that performs a single or double rotation.
* Because the result is attached to the parent, there are four cases.
* Called by handleReorient.
* item is the item in handleReorient.
* parent is the parent of the root of the rotated subtree.
* Return the root of the rotated subtree.
*/
template <class Comparable>
RedBlackNode<Comparable> *
RedBlackTree<Comparable>::rotate( const Comparable & item,
RedBlackNode<Comparable> *theParent ) const
{
if( item < theParent->element )
{
item < theParent->left->element ?
rotateWithLeftChild( theParent->left ) : // LL
rotateWithRightChild( theParent->left ) ; // LR
return theParent->left;
}
else
{
item < theParent->right->element ?
rotateWithLeftChild( theParent->right ) : // RL
rotateWithRightChild( theParent->right ); // RR
return theParent->right;
}
}
/**
* Rotate binary tree node with left child.
*/
template <class Comparable>
void RedBlackTree<Comparable>::
rotateWithLeftChild( RedBlackNode<Comparable> * & k2 ) const
{
RedBlackNode<Comparable> *k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k2 = k1;
}
/**
* Rotate binary tree node with right child.
*/
template <class Comparable>
void RedBlackTree<Comparable>::
rotateWithRightChild( RedBlackNode<Comparable> * & k1 ) const
{
RedBlackNode<Comparable> *k2 = k1->right;
k1->right = k2->left;
k2->left = k1;
k1 = k2;
}
/**
* Internal method to reclaim internal nodes
* in subtree t.
*/
template <class Comparable>
void RedBlackTree<Comparable>::reclaimMemory( RedBlackNode<Comparable> *t ) const
{
if( t != t->left )
{
reclaimMemory( t->left );
reclaimMemory( t->right );
delete t;
}
}
int N, NR;
int main()
{
srand( time( NULL ) );
freopen("hashuri.in", "r", stdin);
freopen("hashuri.out", "w", stdout);
int i, tip, x;
const int ITEM_NOT_FOUND = -999999999;
RedBlackTree<int> TR( ITEM_NOT_FOUND );
scanf("%d ", &N);
for (i = 1; i <= N; i++)
{
scanf("%d %d ", &tip, &x);
if (tip == 1 && TR.find( x ) == ITEM_NOT_FOUND ) TR.insert( x );
if (tip == 2) TR.remove(x);
if (tip == 3) printf("%d\n", TR.find(x) != ITEM_NOT_FOUND);
}
return 0;
}