1
0
forked from 0ad/0ad
0ad/source/dcdt/se/sr_tree.h

290 lines
12 KiB
C++

/** \file sr_tree.h
* A red-black balanced search tree */
# ifndef SR_TREE_H
# define SR_TREE_H
# include "sr_class_manager.h"
# include "sr_output.h"
/*! \class SrTreeNode sr_tree_node.h
\brief A red-black node for SrTree
SrTreeNode is the node that classes should derive in order to be
inserted in SrTree. This class has all its data members as public,
so that the user can use them as needed. There are no methods for
manipulation of the nodes inside this class, all such manipulation
methods are in SrTreeBase. */
class SrTreeNode
{ public :
/*! The color type of the node. */
enum Color { Red, Black };
/*! SrTreeNode::null is initialized in sr_tree_node.cpp, and serves
as a sentinel indicating a null node. SrTreeNode::null is a black
node where its pointers are initialized as pointing to itself, but
the parent pointer may keep arbitrary values during manipulation
inside SrTreeBase. */
static SrTreeNode* null;
public :
Color color; //!> Color of the node.
SrTreeNode* parent; //!> Pointer to node's parent.
SrTreeNode* left; //!> Pointer to node's left child.
SrTreeNode* right; //!> Pointer to node's righ child.
public :
/*! Default Constructor. */
SrTreeNode ( Color c=Red ) : color(c), parent(null), left(null), right(null) {}
public :
/*! Sets all links to SrTreeNode::null, but leaves color unchanged. */
void init () { parent=left=right=null; }
};
/*! \class SrTreeBase sr_tree.h
\brief red-black tree base class
This class contains all methods for tree manipulation. The user should
however use the template class SrTree for an implementation that
includes automatic type casts for the user type. A manager to the
user data is required, which must be a class deriving SrTreeNode.
For details about red black trees, see:
T. H. Cormen, C. E. Leiserson, and R. L. Rivest, "Introduction to Algorithms"
1990, MIT, chapter 14, ISBN 0-262-03141-8
<br><br>
Note:
A binary search tree is a red-black tree if it satisfies : <br>
1. Every node is either red or black <br>
2. Every null leaf is black <br>
3. If a node is red then both its children are black <br>
4. Every simple path from a node to a descendant leaf contains the same number of black nodes <br> */
class SrTreeBase
{ private :
SrTreeNode *_root; // the root of the tree
SrTreeNode *_cur; // the current element of the tree
SrClassManagerBase* _man; // manager of user data, that derives SrListNode
int _elements; // number of elements of the tree
int _search_node ( const SrTreeNode* key );
void _rotate_right ( SrTreeNode* x );
void _rotate_left ( SrTreeNode* x );
void _rebalance ( SrTreeNode* x );
void _fix_remove ( SrTreeNode* x );
public :
/*! Initiates an empty tree. The class manager must manage a user class
deriving from SrTreeNode. */
SrTreeBase ( SrClassManagerBase* m );
/*! Copy constructor. The class manager of t is shared. */
SrTreeBase ( const SrTreeBase& t );
/*! Destructor. */
~SrTreeBase ();
/*! Deletes all elements of the tree. */
void init ();
/*! Returns true iff there is no nodes in the tree. */
bool empty () const { return _root==SrTreeNode::null? true:false; }
/*! Returns the number of elements of the tree. */
int elements () const { return _elements; }
/*! Method to find the minimum node of the subtree rooted at the given node x. */
SrTreeNode* get_min ( SrTreeNode* x ) const;
/*! Method to find the maximum node of the subtree rooted at the given node x. */
SrTreeNode* get_max ( SrTreeNode* x ) const;
/*! Method to find the successor node of the given node x in the tree. */
SrTreeNode* get_next ( SrTreeNode* x ) const;
/*! Method to find the predecessor node of the given node x in the tree. */
SrTreeNode* get_prior ( SrTreeNode* x ) const;
/*! Returns the current element being pointed, that will be SrTreeNode::null
if the tree is emptyis returned. */
SrTreeNode* cur () const { return _cur; }
/*! Sets the current element to be c, which must be a node of the tree. */
void cur ( SrTreeNode* c ) { _cur = c; }
/*! Returns the root of the tree, that will be SrTreeNode::null if the tree is empty. */
SrTreeNode* root () { return _root; }
/*! Returns the first element of the tree, ie, the minimum according
to the comparison function. */
SrTreeNode* first () const { return get_min(_root); }
/*! Returns the last element of the tree, ie, the maximum. */
SrTreeNode* last () const { return get_max(_root); }
/*! Will put the current position cur() pointing to the node with minimum value.
If the list is empty, cur will point to SrTreeNode::null. */
void gofirst () { _cur = get_min(_root); }
/*! Will put the current position cur() pointing to the node with maximum value.
If the list is empty, cur will point to SrTreeNode::null. */
void golast () { _cur = get_max(_root); }
/*! Returns the next element of the current position cur().
If cur points to null, SrTreeNode::Null is returned. */
SrTreeNode* curnext () const { return get_next(_cur); }
/*! Returns the prior element of the current position cur().
If cur points to null, SrTreeNode::null is returned. */
SrTreeNode* curprior () const { return get_prior(_cur); }
/*! Will put the current position cur() pointing to the next
node curnext(), cur can become SrTreeNode::null. */
void gonext () { _cur = get_next(_cur); }
/*! Will put the current position cur() pointing to the prior
link curprior(), cur can become SrTreeNode::null. */
void goprior () { _cur = get_prior(_cur); }
/*! Returns a pointer to the item that is equal to the given key, or 0
if it could not find the key in the tree. cur will be the last node
visited during the search. */
SrTreeNode* search ( const SrTreeNode *key );
/*! If inserted, will return key, otherwise will return 0, and cur will
point to key. Duplication is not allowed. */
SrTreeNode* insert ( SrTreeNode* key );
/*! Tries to insert key using method insert(). In case of duplication
key is not inserted, key is deleted, and 0 is returned. The returned
node will be pointing to key in case of sucees, or pointing to the
node in the tree that is equal to key in case of failure. In all cases,
cur will be the last node visited during the search for key. */
SrTreeNode* insert_or_del ( SrTreeNode* key );
/*! Duplicates and inserts all elements of t in the tree. */
void insert_tree ( const SrTreeBase& t );
/*! Extracts node z that must be inside the tree; z is returned. */
SrTreeNode* extract ( SrTreeNode* z );
/*! Removes and delete node z, which must be inside the tree. */
void remove ( SrTreeNode* z );
/*! Extracts the item equal to the key and return it or 0 if the
key was not found. */
SrTreeNode* search_and_extract ( const SrTreeNode* key );
/*! Removes and deletes the item equal to the key. Returns true if a node
is found and deleted, otherwise false is returned. */
bool search_and_remove ( const SrTreeNode* key );
/*! Take control of the tree in t, and set t to an empty tree. Both
trees must manage the same derived class of SrTreeNode. */
void take_data ( SrTreeBase& t );
/*! Copy operator */
void operator= ( const SrTreeBase& t );
/*! Outputs the tree in the format: [e1 e2 en] */
friend SrOutput& operator<< ( SrOutput& o, const SrTreeBase& t );
};
/*! \class SrTree sr_tree.h
\brief red-black balanced tree
SrTree defines automatic type casts to the user type, which must
derive SrTreeNode. To traverse the tree, the first, last, next,
and prior keywords are related to the order defined by the comparison
method in the class manager. For documentation of the methods
see the documentation of the base class SrTreeBase methods. */
template <class X>
class SrTree : public SrTreeBase
{ public:
/*! Default constructor that automatically creates a SrClassManager<X>. */
SrTree () : SrTreeBase ( new SrClassManager<X> ) {}
/*! Constructor with a given class manager. */
SrTree ( SrClassManagerBase* m ) : SrTreeBase ( m ) {}
/*! Copy constructor with class manager sharing. */
SrTree ( const SrTree& t ) : SrTreeBase ( t ) {}
X* cur () { return (X*)SrTreeBase::cur(); }
void cur ( X* c ) { SrTreeBase::cur((SrTreeNode*)c); }
X* root () { return (X*)SrTreeBase::root(); }
X* first () { return (X*) SrTreeBase::first(); }
X* last () { return (X*) SrTreeBase::last(); }
X* curnext () const { return (X*)SrTreeBase::curnext(); }
X* curprior () const { return (X*)SrTreeBase::curprior(); }
X* search ( const X* key ) { return (X*)SrTreeBase::search(key); }
X* insert ( X* key ) { return (X*)SrTreeBase::insert(key); }
X* insert_or_del ( X* key ) { return (X*)SrTreeBase::insert_or_del(key); }
X* extract ( X* n ) { return (X*) SrTreeBase::extract(n); }
void remove ( X* n ) { SrTreeBase::remove(n); }
X* search_and_extract ( const X* key ) { return (X*) SrTreeBase::search_and_extract(key); }
bool search_and_remove ( const X* key ) { return SrTreeBase::search_and_remove(key); }
};
/*! Base class for iterating over trees. */
class SrTreeIteratorBase
{ private :
SrTreeNode* _cur;
SrTreeNode* _first;
SrTreeNode* _last;
const SrTreeBase& _tree;
public :
/*! Constructor */
SrTreeIteratorBase ( const SrTreeBase& t );
/*! Returns the current node being pointed by the iterator */
SrTreeNode* cur () const { return _cur; }
/*! Returns the first node in the associated tree */
SrTreeNode* getfirst () const { return _first; }
/*! Returns the last node in the associated tree */
SrTreeNode* getlast () const { return _last; }
/*! Must be called each time the associate tree is changed */
void reset ();
/*! Points the iterator to the first element. */
void first () { _cur=_first; }
/*! Points the iterator to the last element. */
void last () { _cur=_last; }
/*! Advances the current position of the iterator to the next one */
void next () { _cur=_tree.get_next(_cur); }
/*! Walk back the current position of the iterator of one position */
void prior () { _cur=_tree.get_prior(_cur); }
/*! Returns true if get() points to a valid position */
bool inrange () { return _cur==SrTreeNode::null? false:true; }
/*! Returns the current element, can return SrTreeNode::null */
SrTreeNode* get () { return _cur; }
/*! Returns true if the current position is pointing to the last element. */
bool inlast () const { return _cur==_last? true:false; }
/*! Returns true if the current position is pointing to the first element */
bool infirst () const { return _cur==_first? true:false; }
};
/*! Derives SrTreeIteratorBase providing correct type casts for the user type */
template <class X>
class SrTreeIterator : public SrTreeIteratorBase
{ public :
SrTreeIterator ( const SrTree<X>& s ) : SrTreeIteratorBase(s) {}
X* get () { return (X*)SrTreeIteratorBase::get(); }
X* operator-> () { return (X*)SrTreeIteratorBase::get(); }
};
//============================ End of File =================================
# endif // SR_TREE_H