#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