home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 20.ddi / CLASSSRC.PAK / BINIMP.CPP next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  7.9 KB  |  284 lines

  1. /*------------------------------------------------------------------------*/
  2. /*                                                                        */
  3. /*  BINIMP.CPP                                                            */
  4. /*                                                                        */
  5. /*  Copyright Borland International 1993                                  */
  6. /*  All Rights Reserved                                                   */
  7. /*                                                                        */
  8. /*------------------------------------------------------------------------*/
  9.  
  10. #if !defined( __CLASSLIB_BINIMP_H )
  11. #include "classlib\binimp.h"
  12. #endif  // __CLASSLIB_BINIMP_H
  13.  
  14. TBinarySearchTreeBase::TBinarySearchTreeBase() :
  15.     Root(0),
  16.     ItemsInContainer(0)
  17. {
  18. }
  19.  
  20. int TBinarySearchTreeBase::InsertNode( BinNode *node )
  21. {
  22.     BinNode *Current = Root;
  23.     BinNode *Parent = 0;
  24.     while( Current )
  25.         {
  26.         Parent = Current;
  27.         Current = LessThan( node, Current ) ? Current->Left : Current->Right;
  28.         }
  29.     if( Parent == 0 )
  30.         Root = node;
  31.     else
  32.         {
  33.         if( LessThan( node, Parent ) )
  34.             Parent->Left = node;
  35.         else
  36.             Parent->Right = node;
  37.         }
  38.     ItemsInContainer++;
  39.     return 1;
  40. }
  41.  
  42. int TBinarySearchTreeBase::RemoveNode( BinNode *node, int del )
  43. {
  44.     BinNode *Current = Root;
  45.     BinNode *Parent = 0;
  46.     while( Current )
  47.         {
  48.         if( EqualTo( node, Current ) )
  49.             return RemNode( Current, Parent, del );
  50.         else
  51.             {
  52.             Parent = Current;
  53.             Current = LessThan( node, Current ) ? Current->Left :
  54.                                                   Current->Right;
  55.             }
  56.         }
  57.     return 0;
  58. }
  59.  
  60. TBinarySearchTreeBase::BinNode *TBinarySearchTreeBase::FindNode( BinNode *node )
  61. {
  62.     BinNode *Current = Root;
  63.     while( Current )
  64.         {
  65.         if( EqualTo( node, Current ) )
  66.             return Current;
  67.         else
  68.             Current = LessThan( node, Current ) ? Current->Left :
  69.                                                   Current->Right;
  70.         }
  71.     return 0;
  72. }
  73.  
  74. int TBinarySearchTreeBase::RemNode( BinNode *node, BinNode *parent, int del )
  75. {
  76.     // See R. Sedgewick, "Algorithms, 2nd edition",
  77.     //   Addison-Wesley 1988, p.210.
  78.     BinNode *Original = node;
  79.     if( Original->Right == 0 )
  80.         node = node->Left;
  81.     else if( Original->Right->Left )
  82.         {
  83.         BinNode *Current = Original->Right;
  84.         while( Current->Left->Left )
  85.             Current = Current->Left;
  86.         node = Current->Left;
  87.         Current->Left = node->Right;
  88.         node->Left = Original->Left;
  89.         node->Right = Original->Right;
  90.         }
  91.     else
  92.         {
  93.         node = node->Right;
  94.         node->Left = Original->Left;
  95.         }
  96.     if( parent == 0 )
  97.         Root = node;
  98.     else if( LessThan( Original, parent ) )
  99.         parent->Left = node;
  100.     else
  101.         parent->Right = node;
  102.  
  103.     DeleteNode( Original, del );
  104.     ItemsInContainer--;
  105.     return 1;
  106. }
  107.  
  108. class TBinaryTreeKiller : public TBinaryTreeInternalIteratorBase
  109. {
  110.  
  111. public:
  112.  
  113.     TBinaryTreeKiller( TBinarySearchTreeBase& tree, int del ) :
  114.         TBinaryTreeInternalIteratorBase( tree, TBinarySearchTreeBase::PostOrder ),
  115.         Del(del) {}
  116.  
  117. private:
  118.  
  119.     virtual void Apply( TBinarySearchTreeBase::BinNode _FAR *node,
  120.                         TBinarySearchTreeBase::BinNode _FAR *parent );
  121.  
  122.     int Del;
  123.  
  124.     TBinaryTreeKiller( const TBinaryTreeKiller& );
  125.     const TBinaryTreeKiller& operator = ( const TBinaryTreeKiller& );
  126.  
  127. };
  128.  
  129. void TBinaryTreeKiller::Apply( TBinarySearchTreeBase::BinNode _FAR *node,
  130.                            TBinarySearchTreeBase::BinNode _FAR *parent )
  131. {
  132.     Tree().RemNode( node, parent, Del );
  133. }
  134.  
  135. void TBinarySearchTreeBase::Flush( int del )
  136. {
  137.     if( Root != 0 )
  138.         TBinaryTreeKiller( *this, del ).Iterate();
  139. }
  140.  
  141. void TBinaryTreeInternalIteratorBase::Iterate()
  142. {
  143.     TBinarySearchTreeBase::BinNode _FAR *Current = Node;
  144.     TBinarySearchTreeBase::BinNode _FAR *Prev = 0;
  145.     TBinarySearchTreeBase::BinNode _FAR *Next = 0;
  146. step2:
  147.     if( Order == TBinarySearchTreeBase::PreOrder )
  148.         Apply( Current, 0 );
  149.     Next = Current->Left;
  150.     if( Next != 0 )
  151.         {
  152.         Current->Left = Prev;
  153.         Prev = Current;
  154.         Current = Next;
  155.         goto step2;
  156.         }
  157. step4:
  158.     if( Order == TBinarySearchTreeBase::InOrder )
  159.         Apply( Current, 0 );
  160.     Next = Current->Right;
  161.     if( Next != 0 )
  162.         {
  163.         Current->Right = Prev;
  164.         Prev = Current;
  165.         Current = Next;
  166.         goto step2;
  167.         }
  168. step6:
  169.     if( Prev == 0 )
  170.         {
  171.         if( Order == TBinarySearchTreeBase::PostOrder )
  172.             Apply( Current, 0 );
  173.         return;
  174.         }
  175.     if( Tree().LessThan( Current, Prev ) )
  176.         {
  177.         TBinarySearchTreeBase::BinNode _FAR *Temp = Current;
  178.         Next = Prev->Left;
  179.         Prev->Left = Current;
  180.         Current = Prev;
  181.         Prev = Next;
  182.         if( Order == TBinarySearchTreeBase::PostOrder )
  183.             Apply( Temp, Current );
  184.         goto step4;
  185.         }
  186.     else
  187.         {
  188.         TBinarySearchTreeBase::BinNode _FAR *Temp = Current;
  189.         Next = Prev->Right;
  190.         Prev->Right = Current;
  191.         Current = Prev;
  192.         Prev = Next;
  193.         if( Order == TBinarySearchTreeBase::PostOrder )
  194.             Apply( Temp, Current );
  195.         goto step6;
  196.         }
  197. }
  198.  
  199. TBinaryTreeExternalIteratorBase::TBinaryTreeExternalIteratorBase( TBinarySearchTreeBase& tree, TBinarySearchTreeBase::IteratorOrder order ) :
  200.     Tree(&tree),
  201.     Current( tree.Root ),
  202.     Order( order )
  203. {
  204.     Restart();
  205. }
  206.  
  207. void TBinaryTreeExternalIteratorBase::Restart()
  208. {
  209.     Stack.Flush();
  210.     Current = Tree->Root;
  211.     LeftVisited = RightVisited = 0;
  212.     Processed = 0;
  213. }
  214.  
  215. TBinarySearchTreeBase::BinNode *TBinaryTreeExternalIteratorBase::Next()
  216. {
  217.     if( Current == 0 )
  218.         return 0;
  219.     for(;;)
  220.         {
  221.         if( Order == TBinarySearchTreeBase::PreOrder && !Processed )
  222.             {
  223.             Processed = 1;
  224.             return Current;
  225.             }
  226.  
  227.         if( Current->Left != 0 && !LeftVisited )
  228.             {
  229.             Stack.Push( Current );
  230.             Current = Current->Left;
  231.             LeftVisited = RightVisited = 0;
  232.             Processed = 0;
  233.             }
  234.         else if( Current->Right != 0 && !RightVisited )
  235.             {
  236.             TBinarySearchTreeBase::BinNode *Res = 0;
  237.             if( Order == TBinarySearchTreeBase::InOrder )
  238.                 Res = Current;
  239.             Stack.Push( Current );
  240.             Current = Current->Right;
  241.             LeftVisited = RightVisited = 0;
  242.             Processed = 0;
  243.             if( Res != 0 )
  244.                 return Res;
  245.             }
  246.         else
  247.             {
  248.             if( Stack.IsEmpty() )
  249.                 {
  250.                 if( Processed == 0 )
  251.                     {
  252.                     Processed = 1;
  253.                     }
  254.                 else
  255.                     {
  256.                     Current = 0;
  257.                     }
  258.                 return Current;
  259.                 }
  260.             else
  261.                 {
  262.                 TBinarySearchTreeBase::BinNode *Res;
  263.                 if( Order == TBinarySearchTreeBase::PostOrder ||
  264.                    (Order == TBinarySearchTreeBase::InOrder && IsInOrder()) )
  265.                     {
  266.                     Res = Current;
  267.                     Processed = 0;
  268.                     }
  269.                 else
  270.                     {
  271.                     Res = 0;
  272.                     Processed = 1;
  273.                     }
  274.                 LeftVisited = 1;
  275.                 RightVisited = !Tree->LessThan( Current, Stack.Top() );
  276.                 Current = Stack.Pop();
  277.                 if( Res != 0 )
  278.                     return Res;
  279.                 }
  280.             }
  281.         }
  282. }
  283.  
  284.