#ifndef __BINTREE_H
#define __BINTREE_H
#include "listman.h"
#include "vector.h"
/* Select node type and file management scheme */
#define Nd TDBinarySearchTreeNode
#ifndef FM
#define FM DirectFile /* CachedFile on code disk */
#endif
#define CACHESIZE 25 /* #default cache nodes */
template <class T> class TDBinarySearchTree
{
TDListManager<Nd<T>, FM> *_Lm;
public:
TDBinarySearchTree( const char *fname = 0,
int nn = CACHESIZE) {
_Lm = new TDListManager
<Nd<T>, FM> (fname, nn, 0);
}
~TDBinarySearchTree() { delete _Lm; }
ulong ItemCount() const
{ return _Lm->ItemCount(); }
void ItemCount( ulong c )
{ _Lm->ItemCount( c ); }
ulong ListSize() const
{ return _Lm->ListSize(); }
int Add( const T& );
void ForEach( int (*)(T&, void *), void * );
friend TDBinarySearchTree<T>& operator <<
( TDBinarySearchTree<T>& bt, const T& obj )
{ bt.Add( obj );
return bt;
}
};
template <class T>
int TDBinarySearchTree<T>::Add( const T& item )
{ Nd<T> newnode, pnode;
filepos p, q;
int addleft;
_Lm->GetFree( newnode );
q = _Lm->Head();
while( q ) {
p = q;
_Lm->ReadNode( pnode, p );
addleft = 0;
if( item < pnode.Data ) {
q = pnode.Left;
addleft = 1;
}
else
q = pnode.Right;
}
if( _Lm->Head() == 0 )
_Lm->Head( newnode.Free );
else {
if( addleft )
pnode.Left = newnode.Free;
else
pnode.Right = newnode.Free;
_Lm->WriteNode( pnode, pnode.Free );
}
newnode.Left = newnode.Right = 0;
newnode.Data = item;
_Lm->WriteNode( newnode, newnode.Free );
ItemCount( ItemCount() + 1 );
return 1;
}
template <class T> void TDBinarySearchTree<T>::
ForEach( int (*ifn)(T&, void *), void *args )
{ /* Do an inorder traversal. ifn() returns !0 if
* node was modified and must be updated.
*/
Nd<T> node;
filepos p;
TDStackAsVector<filepos> stk; /* temp stack */
p = _Lm->Head();
while( 1 ) {
while( p ) { /* traverse left subtree */
_Lm->ReadNode(node, p);
stk.Push(p);
p = node.Left;
}
if( stk.Pop(p) == 0 )
break;
_Lm->ReadNode(node, p);
if( ifn( node.Data, args ) ) /* update node */
_Lm->WriteNode(node, p); /* if modified */
p = node.Right; /* goto right subtree */
}
}
#endif // EOF