AVL tree/C++

From Rosetta Code

Code[edit]

// The set template is the primary class of AVL Trees.
// The system is set up to add templates including tree and map.

#include<iostream>

class treeException
{
  public:

   treeException() {}
};

 class EntryAlreadyExistsException : public treeException
 {
  public:
    EntryAlreadyExistsException() {}
 };

 class EntryNotFoundException : public treeException
 {
  public:
    EntryNotFoundException()  {}
 };

 class InvalidSetOperationException : public treeException
 {
  public:
    InvalidSetOperationException() {}
 };

 class IsHeaderException : public treeException
 {
  public:
    IsHeaderException() {}
 };

struct State
 {
  enum
  {
   Header,
   Balanced,
   LeftHigh,
   RightHigh
  };
 };

struct Node  // Base Node Class for all Trees
{
 Node* Left;
 Node* Right;
 Node* Parent;
 char Balance;

 Node()
 {
  Balance = State::Header;
  Left    = this;
  Right   = this;
  Parent  = 0;
 }

 Node(Node* ParentSet)
 {
  Balance = State::Balanced;
  Left    = 0;
  Right   = 0;
  Parent  = ParentSet;
 }

 bool IsHeader() const {return !Balance;}
};

struct Direction
{
 enum {FromLeft, FromRight};
};

inline void SwapNodeReference(Node*& first, Node*& second)
{Node* temporary = first; first = second; second = temporary;}

void SwapNodes(Node* A, Node* B)
{
 if (B == A->Left)
  {
   if (B->Left) B->Left->Parent = A;
   if (B->Right) B->Right->Parent = A;

   if (A->Right) A->Right->Parent = B;

   if (!A->Parent->IsHeader())
    {
     if (A->Parent->Left == A)
      A->Parent->Left = B;
     else
      A->Parent->Right = B;
    }
   else A->Parent->Parent = B;

   B->Parent = A->Parent;
   A->Parent = B;

   A->Left = B->Left;
   B->Left = A;

   SwapNodeReference(A->Right,B->Right);
  }
 else if (B == A->Right)
  {
   if (B->Right) B->Right->Parent = A;
   if (B->Left) B->Left->Parent = A;

   if (A->Left) A->Left->Parent = B;

   if (!A->Parent->IsHeader())
    {
     if (A->Parent->Left == A)
      A->Parent->Left = B;
     else
      A->Parent->Right = B;
    }
   else A->Parent->Parent = B;

   B->Parent = A->Parent;
   A->Parent = B;

   A->Right = B->Right;
   B->Right = A;

   SwapNodeReference(A->Left,B->Left);
  }
 else if (A == B->Left)
  {
   if (A->Left) A->Left->Parent = B;
   if (A->Right) A->Right->Parent = B;

   if (B->Right) B->Right->Parent = A;

   if (!B->Parent->IsHeader())
    {
     if (B->Parent->Left == B)
      B->Parent->Left = A;
     else
      B->Parent->Right = A;
    }
   else B->Parent->Parent = A;

   A->Parent = B->Parent;
   B->Parent = A;

   B->Left = A->Left;
   A->Left = B;

   SwapNodeReference(A->Right,B->Right);
  }
 else if (A == B->Right)
  {
   if (A->Right) A->Right->Parent = B;
   if (A->Left) A->Left->Parent = B;

   if (B->Left) B->Left->Parent = A;

   if (!B->Parent->IsHeader())
    {
     if (B->Parent->Left == B)
      B->Parent->Left = A;
     else
      B->Parent->Right = A;
    }
   else B->Parent->Parent = A;

   A->Parent = B->Parent;
   B->Parent = A;

   B->Right = A->Right;
   A->Right = B;

   SwapNodeReference(A->Left,B->Left);
  }
 else
  {
   if (A->Parent == B->Parent)
    SwapNodeReference(A->Parent->Left,A->Parent->Right);
   else
    { 
     if (!A->Parent->IsHeader())
      {
       if (A->Parent->Left == A)
        A->Parent->Left = B;
       else
        A->Parent->Right = B;
      }
     else A->Parent->Parent = B;

     if (!B->Parent->IsHeader())
      {
       if (B->Parent->Left == B)
        B->Parent->Left = A;
       else
        B->Parent->Right = A;
      }
     else B->Parent->Parent = A;
    }

   if (B->Left)  B->Left->Parent = A;
   if (B->Right) B->Right->Parent = A;

   if (A->Left)  A->Left->Parent = B;
   if (A->Right) A->Right->Parent = B;

   SwapNodeReference(A->Left,B->Left);
   SwapNodeReference(A->Right,B->Right);
   SwapNodeReference(A->Parent,B->Parent);
  }

 unsigned long Balance = A->Balance;
 A->Balance = B->Balance;
 B->Balance=(char)Balance;
}

inline void RotateLeft(Node*& Root)
{
 Node* Parent = Root->Parent;
 Node* x = Root->Right;

 Root->Parent = x;
 x->Parent = Parent;
 if (x->Left) x->Left->Parent = Root; 

 Root->Right = x->Left;
 x->Left = Root;
 Root = x;
}    

inline void RotateRight(Node*& Root)
{
 Node* Parent = Root->Parent;
 Node* x = Root->Left;

 Root->Parent = x;
 x->Parent = Parent;
 if (x->Right) x->Right->Parent = Root; 

 Root->Left = x->Right;
 x->Right = Root;
 Root = x;
} 

inline void BalanceLeft(Node*& Root)
{
 Node* Left = Root->Left; // Left Subtree of Root Node

 switch (Left->Balance)
  {
   case State::LeftHigh:
    Root->Balance = State::Balanced;
    Left->Balance = State::Balanced;
    RotateRight(Root);
    break;           
    
   case State::RightHigh:
    {
     Node* subRight = Left->Right;  // Right subtree of Left
     switch (subRight->Balance)
      {
       case State::Balanced:
        Root->Balance = State::Balanced;
        Left->Balance = State::Balanced;
        break;

       case State::RightHigh:
        Root->Balance = State::Balanced;
        Left->Balance = State::LeftHigh;
        break;

       case State::LeftHigh:
        Root->Balance = State::RightHigh;
        Left->Balance = State::Balanced;
        break;
      }
     subRight->Balance = State::Balanced;
     RotateLeft(Left);
     Root->Left = Left;
     RotateRight(Root);
    }
    break;

   case State::Balanced:
    Root->Balance = State::LeftHigh;
    Left->Balance = State::RightHigh;
    RotateRight(Root);
    break;           
  }
} 

inline void BalanceRight(Node*& Root)
{
 Node* Right = Root->Right; // Right Subtree of Root Node

 switch (Right->Balance)
  {
   case State::RightHigh:
    Root ->Balance = State::Balanced;
    Right->Balance = State::Balanced;
    RotateLeft(Root);
    break;

   case State::LeftHigh:
    {
     Node* subLeft = Right->Left; // Left Subtree of Right
     switch (subLeft->Balance)
      {
       case State::Balanced:
        Root ->Balance = State::Balanced;
        Right->Balance = State::Balanced;
        break;

       case State::LeftHigh:
        Root ->Balance = State::Balanced;
        Right->Balance = State::RightHigh;
        break;

       case State::RightHigh:
        Root ->Balance = State::LeftHigh;
        Right->Balance = State::Balanced;
        break;
      }
     subLeft->Balance = State::Balanced;
     RotateRight(Right);
     Root->Right = Right;
     RotateLeft(Root);
    }
    break;         

   case State::Balanced:
    Root ->Balance = State::RightHigh;
    Right->Balance = State::LeftHigh;
    RotateLeft(Root);
    break;           
  }
} 

inline void BalanceTree(Node* Root, unsigned long From)
{
  bool Taller = true;

  while (Taller)
   {
    Node* Parent = Root->Parent;
    unsigned long NextFrom = (Parent->Left == Root) ? Direction::FromLeft : Direction::FromRight;

    if (From == Direction::FromLeft)
    {
     switch (Root->Balance)
      {
       case State::LeftHigh:
        if (Parent->IsHeader())
          BalanceLeft(Parent->Parent);
        else if (Parent->Left == Root)
          BalanceLeft(Parent->Left);
        else
          BalanceLeft(Parent->Right);
        Taller = false;
        break;

        case State::Balanced:
         Root->Balance = State::LeftHigh;
         Taller = true;
         break;

        case State::RightHigh:
         Root->Balance = State::Balanced;
         Taller = false;
         break;
       }
     }
    else
     {
      switch (Root->Balance)
       {
        case State::LeftHigh:
         Root->Balance = State::Balanced;
         Taller = false;
         break;

        case State::Balanced:
         Root->Balance = State::RightHigh;
         Taller = true;
         break;

        case State::RightHigh:
         if (Parent->IsHeader())
           BalanceRight(Parent->Parent);
         else if (Parent->Left == Root)
           BalanceRight(Parent->Left);
         else
           BalanceRight(Parent->Right);
         Taller = false;
         break;
        }
      }

      if (Taller) // skip up a level
      {
       if (Parent->IsHeader())
        Taller = false;
       else
       {
        Root = Parent;
        From = NextFrom;
       }
     }
   }
 }


inline void BalanceTreeRemove(Node* Root, unsigned long From)
{
  if (Root->IsHeader()) return;
  bool Shorter = true;

  while (Shorter)
   {
    Node* Parent = Root->Parent;
    unsigned long NextFrom = (Parent->Left == Root) ? Direction::FromLeft : Direction::FromRight;

    if (From == Direction::FromLeft)
     {
      switch (Root->Balance)
       {
        case State::LeftHigh:
         Root->Balance = State::Balanced;
         Shorter = true;
         break;

        case State::Balanced:
         Root->Balance = State::RightHigh;
         Shorter = false;
         break;

        case State::RightHigh:
         if (Root->Right->Balance == State::Balanced)
          Shorter = false;
         else
          Shorter = true;
        if (Parent->IsHeader())
         BalanceRight(Parent->Parent);
        else if (Parent->Left == Root)
         BalanceRight(Parent->Left);
        else
         BalanceRight(Parent->Right);
        break;
       }
    }
   else
    {
     switch (Root->Balance)
      {
       case State::RightHigh:
        Root->Balance = State::Balanced;
        Shorter = true;
        break;

       case State::Balanced:
        Root->Balance = State::LeftHigh;
        Shorter = false;
        break;

       case State::LeftHigh:
        if (Root->Left->Balance == State::Balanced)
         Shorter = false;
        else
         Shorter = true;
        if (Parent->IsHeader())
          BalanceLeft(Parent->Parent);
        else if (Parent->Left == Root)
          BalanceLeft(Parent->Left);
        else
          BalanceLeft(Parent->Right);
        break;
       }
     }

     if (Shorter)
      {
       if (Parent->IsHeader())
        Shorter = false;
       else
        {
         From = NextFrom;
         Root = Parent;
        }
      }
   }
}

Node* PreviousItem(Node* node)
{
 if (node->IsHeader()) {return node->Right;}

 else if (node->Left != 0)
  {
   Node* y = node->Left;
   while (y->Right != 0) y = y->Right;
   node = y;
  }
 else
  {
   Node* y = node->Parent;
   if (y->IsHeader()) return y;
   while (node == y->Left) {node = y; y = y->Parent;}
   node = y;
  }
 return node;
}

Node* NextItem(Node* node)
{
 if (node->IsHeader()) return node->Left;

 if (node->Right != 0)
  {
   node = node->Right;
   while (node->Left != 0) node = node->Left;
  }
 else
  {
   Node* y = node->Parent;
   if (y->IsHeader()) return y;
   while (node == y->Right) {node = y; y = y->Parent;}
   node = y;
  }
 return node;
}

inline Node* Minimum(Node* node)
{
 while (node->Left) node=node->Left;
 return node;
}

inline Node* Maximum(Node* node)
{
 while (node->Right) node=node->Right;
 return node;
}

void AdjustAdd(Node* Root)
{
 Node* Header = Root->Parent;
 while (!Header->IsHeader()) Header=Header->Parent;

 if (Root->Parent->Left == Root)
 {
  BalanceTree(Root->Parent,Direction::FromLeft);
  if (Header->Left == Root->Parent) Header->Left = Root;
 }
 else
 {
  BalanceTree(Root->Parent,Direction::FromRight);
  if (Header->Right == Root->Parent) Header->Right = Root;
 }
}

void AdjustRemove(Node* Parent, unsigned long Direction)
{
 BalanceTreeRemove(Parent,Direction);
 
 Node* Header = Parent;
 while (!Header->IsHeader()) Header=Header->Parent;

 if (Header->Parent == 0)
 {
  Header->Left = Header;
  Header->Right = Header;
 }
 else
 {
  Header->Left = Minimum(Header->Parent);
  Header->Right = Maximum(Header->Parent);
 }
}

unsigned long Depth(const Node* root)
{
 if (root)
  {
   unsigned long left  = root->Left  ? Depth(root->Left)  : 0;
   unsigned long right = root->Right ? Depth(root->Right) : 0;
   return left < right ? right+1 : left+1;
  }
 else
  return 0;
}


unsigned long Count(const Node* root)
{
 if (root)
  {
   unsigned long left  = root->Left  ? Count(root->Left)  : 0;
   unsigned long right = root->Right ? Count(root->Right) : 0;
   return left + right + 1;
  }
 else
  return 0;
}

struct setOperation
{
 enum
 {
  Union,
  Intersection,
  SymmetricDifference,
  Difference,
 };
};

template <class U, class V>
inline int compare(const U& u, const V& v)
{if (u < v) return -1; else if (v < u) return 1; else return 0;}

template<class T>
struct setNode : public Node
{
 T Element;

 setNode(const T& ElementSet,
         Node* Parent) : Node(Parent), Element(ElementSet) {}

 operator T&() {return Element;}
};

template <class T>
class setIterator
{
 public:

  Node* _node; 

  setIterator() : _node(0) {}

  setIterator(Node* in) : _node(in) {}

  setIterator(const setIterator<T>& i) : _node(i._node) {}

  T& operator*() const
  {
   return ((setNode<T>*)_node)->Element;
  }

  T* operator->() const
  {
   return &((setNode<T>*)_node)->Element;
  }

  T* operator&() const
  {
   return &((setNode<T>*)_node)->Element;
  }

  setIterator<T>& operator++()
  {_node = NextItem(_node); return *this;}

  setIterator<T> operator++(int)
  {setIterator<T> save = *this; ++*this ;return save;}

  setIterator<T>& operator+=(unsigned long increment)
  {for (unsigned long i=0; i<increment; i++) ++*this; return *this;}

  setIterator<T> operator+(unsigned long increment) const
  {
   setIterator<T> result(*this);
   for (unsigned long i=0; i<increment; i++) ++result;
   return result;
  }

  setIterator<T>& operator--()
  {_node = PreviousItem(_node); return *this;}

  setIterator<T> operator--(int)
  {setIterator<T> save = *this; --*this ;return save;}

  setIterator<T>& operator-=(unsigned long decrement)
  {for (unsigned long i=0; i<decrement; i++) --*this; return *this;}

  setIterator<T> operator-(unsigned long decrement) const
  {
   setIterator<T> result(*this);
   for (unsigned long i=0; i<decrement; i++) --result;
   return result;
  }

  bool operator==(const setIterator<T>& y) const {return _node == y._node;}

  bool operator!=(const setIterator<T>& y) const {return _node != y._node;}

  const T& operator[](long i) const {return i>=0 ? *(*this + i) : *(*this - -i);}  

  long operator-(setIterator<T> iter) const
  {
   long result=0;
   while (iter++ != *this) {result++;}
   return result;
  }

  bool IsHeader() const {return _node->IsHeader();}
};

template <class T>
class constSetIterator
{
 public:

  const Node* _node; 

  constSetIterator() : _node(0) {}

  constSetIterator(const Node* in) : _node(in) {}

  constSetIterator(const constSetIterator<T>& i) : _node(i._node) {}

  constSetIterator(const setIterator<T>& i) : _node(i._node) {}

  const T& operator*() const
  {
   return ((setNode<T>*)_node)->Element;
  }

  const T* operator->() const
  {
   return &((setNode<T>*)_node)->Element;
  }

  const T* operator&() const
  {
   return &((setNode<T>*)_node)->Element;
  }

  constSetIterator<T>& operator++()
  {_node = NextItem((Node*)_node); return *this;}

  constSetIterator<T> operator++(int)
  {constSetIterator<T> save = *this; ++*this ;return save;}

  constSetIterator<T>& operator+=(unsigned long increment)
  {for (unsigned long i=0; i<increment; i++) ++*this; return *this;}

  constSetIterator<T> operator+(unsigned long increment) const
  {
   constSetIterator<T> result(*this);
   for (unsigned long i=0; i<increment; i++) ++result;
   return result;
  }

  constSetIterator<T>& operator--()
  {_node = PreviousItem((Node*)_node); return *this;}

  constSetIterator<T> operator--(int)
  {setIterator save = *this; --*this ;return save;}

  constSetIterator<T>& operator-=(unsigned long decrement)
  {for (unsigned long i=0; i<decrement; i++) --*this; return *this;}

  constSetIterator<T> operator-(unsigned long decrement) const
  {
   constSetIterator<T> result(*this);
   for (unsigned long i=0; i<decrement; i++) --result;
   return result;
  }

  bool operator==(const constSetIterator<T>& y) const {return _node == y._node;}

  bool operator!=(const constSetIterator<T>& y) const {return _node != y._node;}

  const T& operator[](long i) const {return i>=0 ? *(*this + i) : *(*this - -i);}  

  long operator-(constSetIterator<T> iter) const
  {
   long result=0;
   while (iter++ != *this) {result++;}
   return result;
  }

  bool IsHeader() const {return _node->IsHeader;}
};

template <class T>
class set
{
 public:

  typedef int (*keyCompare)(const T&,const T&);

 protected:

  Node Header;
  keyCompare Compare;

 public:

  // *** iterators ***

  typedef setIterator<T> iterator;

  typedef constSetIterator<T> const_iterator;

  // *** constructors, destructor, operators ***

  set(keyCompare C=compare) : Compare(C) {}

  set(const set<T>& copy) : Compare(copy.Compare)
  {
   Copy((setNode<T>*)copy.Header.Parent);
  }

  set(const set& A, const set& B, unsigned long operation)
  {
   Compare = A.Compare;

   const_iterator first1 = A.begin();
   const_iterator last1  = A.end();
   const_iterator first2 = B.begin();
   const_iterator last2  = B.end();

   switch (operation)
    {
     case setOperation::Union:
      {
       while (first1 != last1 && first2 != last2)
        {
         int order = Compare(*first1,*first2);
 
         if (order < 0)
          {
           insert(*first1);
           ++first1;
          }

         else if (order > 0)
          {
           insert(*first2);
           ++first2;
          }

         else
          {
           insert(*first1);
           ++first1; ++first2;
          }
        }

       while (first1 != last1)
        {
         insert(*first1);
         first1++;
        }

       while (first2 != last2)
        {
         insert(*first2);
         first2++;
        }
      }
     break;

     case setOperation::Intersection:
      {
       while (first1 != last1 && first2 != last2)
        {
         int order = Compare(*first1,*first2);

         if (order < 0)
          ++first1;

         else if (order > 0)
          ++first2;

         else
          {
           insert(*first1);
           ++first1; ++first2;
          }
        }
      }
     break;

     case setOperation::SymmetricDifference:
      {
       while (first1 != last1 && first2 != last2)
        {
         int order = Compare(*first1,*first2);

         if (order < 0)
          {
           insert(*first1);
           ++first1;
          }
 
         else if (order > 0)
          {
           insert(*first2);
           ++first2;
          }

         else
          {++first1; ++first2;}
        }

       while (first1 != last1)
        {
         insert(*first1);
         ++first1;
        }

       while (first2 != last2)
        {
         insert(*first2);
         ++first2;
        }
      }
      break;

     case setOperation::Difference:
      {
       while (first1 != last1 && first2 != last2)
        {
         int order = Compare(*first1,*first2);

         if (order < 0)
          {
           insert(*first1);
           ++first1;
          }

         else if (order > 0)
          {
           insert(*first1);
           ++first1; ++first2;
          }

         else
          {++first1; ++first2;}
        }

       while (first1 != last1)
        {
         insert(*first1);
         ++first1;
        }
      }
      break;

     default:
      throw InvalidSetOperationException();
    }
  }

  template<class I>
  set(I first,I last,keyCompare C=compare)
  {
   Compare = C;
   while (first != last) insert(*first++);
  }

  ~set()
  {
   Destroy((setNode<T>*)Header.Parent);
  }

  set<T>& operator=(const set<T>& copy)
  {
   erase();
   Compare = copy.Compare;
   Copy((setNode<T>*)copy.Header.Parent);
   return *this;
  }

  unsigned long length() const {return Count(Header.Parent);}

  operator keyCompare() const {return Compare;}

  set<T>& operator<<(const T& Element) {insert(Element); return *this;}

  set<T>& operator>>(const T& Element) {erase(Element); return *this;}

  // *** methods ***

  iterator begin() {return Header.Left;}

  iterator end() {return &Header;}

  const_iterator begin() const {return Header.Left;}

  const_iterator end() const {return &Header;}

  iterator insert(const T& Element)
  {
   Node* RootNode = Header.Parent;

   if (RootNode == 0)
    {
     RootNode = new setNode<T>(Element,&Header);
     Header.Left = RootNode;
     Header.Right = RootNode;
     Header.Parent = RootNode;
     return RootNode;
    }

   else
    {
     for (; ; )
      {
       int Result = Compare(Element,((setNode<T>*)RootNode)->Element);

       if (Result == 0)
        throw EntryAlreadyExistsException();
 
       else if (Result < 0)
        {
         if (RootNode->Left != 0)
          RootNode = RootNode->Left;
         else
          {
           Node* newNode = new setNode<T>(Element,RootNode);
           RootNode->Left = newNode;
           AdjustAdd(newNode);
           return newNode;
          }
        }

       else
        {
         if (RootNode->Right != 0)
          RootNode = RootNode->Right;
         else
          {
           Node* newNode = new setNode<T>(Element,RootNode);
           RootNode->Right = newNode;
           AdjustAdd(newNode);
           return newNode;
          }
        }
      }
    }
  } 

  void erase(const T& Element)
  {
   Node* RootNode = Header.Parent;

   for (; ; )
    {
     if (RootNode == 0) throw EntryNotFoundException();

     int Result = Compare(Element,((setNode<T>*)RootNode)->Element);

     if (Result < 0)
      RootNode = RootNode->Left;

     else if (Result > 0)
      RootNode = RootNode->Right;

     else // Item is found
      {
       if (RootNode->Left != 0 && RootNode->Right != 0)
        {
         Node* Replace = RootNode->Left;
         while (Replace->Right != 0) Replace = Replace->Right;
         SwapNodes(RootNode, Replace);
        }

       Node* Parent = RootNode->Parent;

       unsigned long From = (Parent->Left == RootNode) ? Direction::FromLeft : Direction::FromRight;
 
       if (RootNode->Left == 0)
        {
         if (Parent == &Header)
          Header.Parent = RootNode->Right;
         else if (From == Direction::FromLeft)
          Parent->Left = RootNode->Right;
         else
          Parent->Right = RootNode->Right;

         if (RootNode->Right != 0) RootNode->Right->Parent = Parent;
        }
       else
        {
         if (Parent == &Header)
          Header.Parent = RootNode->Left;
         else if (From == Direction::FromLeft)
          Parent->Left = RootNode->Left;
         else
          Parent->Right = RootNode->Left;

         if (RootNode->Left != 0) RootNode->Left->Parent = Parent;
        }

       AdjustRemove(Parent, From);
       delete (setNode<T>*)RootNode;
       break;
      }
    }
  }

  void erase(iterator i)
  {
   Node* RootNode = i._node;

   if (RootNode->IsHeader()) throw IsHeaderException();

   if (RootNode->Left != 0 && RootNode->Right != 0)
    {
     Node* Replace = RootNode->Left;
     while (Replace->Right != 0) Replace = Replace->Right;
     SwapNodes(RootNode, Replace);
    }

   Node* Parent = RootNode->Parent;

   unsigned long From = (Parent->Left == RootNode) ? Direction::FromLeft : Direction::FromRight;

   if (RootNode->Left == 0)
    {
     if (Parent == &Header)
      Header.Parent = RootNode->Right;
     else if (From == Direction::FromLeft)
      Parent->Left = RootNode->Right;
     else
      Parent->Right = RootNode->Right;

     if (RootNode->Right != 0) RootNode->Right->Parent = Parent;
    }
   else
    {
     if (Parent == &Header)
      Header.Parent = RootNode->Left;
     else if (From == Direction::FromLeft)
      Parent->Left = RootNode->Left;
     else
      Parent->Right = RootNode->Left;

     if (RootNode->Left != 0) RootNode->Left->Parent = Parent;
    }

   AdjustRemove(Parent, From);
   delete (setNode<T>*)RootNode;
  }

  bool operator[](const T& Element) const {return exists(Element);}

  bool exists(const T& Element) const
  {
   if (!Header.Parent)
    return false;
   else
    {
     const Node* SearchNode = Header.Parent;

     do
      {
       int Result = Compare(Element,((setNode<T>*)SearchNode)->Element);

       if (Result < 0) SearchNode = SearchNode->Left;

       else if (Result > 0) SearchNode = SearchNode->Right;

       else break;

      } while (SearchNode);

     return SearchNode != 0;
    }
  }

  iterator find(const T& Element) const
  {
   if (!Header.Parent)
     throw EntryNotFoundException();
   else
    {
     const Node* SearchNode = Header.Parent;

     do
      {
       int Result = Compare(Element,((setNode<T>*)SearchNode)->Element);

       if (Result < 0) SearchNode = SearchNode->Left;

       else if (Result > 0) SearchNode = SearchNode->Right;

       else break;

      } while (SearchNode);

      if (SearchNode == 0) throw EntryNotFoundException();

     return (Node*)SearchNode;
    } 
  }      

  void erase()
  {
   Destroy((setNode<T>*)Header.Parent);
   Header.Left = &Header;
   Header.Right = &Header;
   Header.Parent = 0;
  }

  iterator after(const T& Element) const
  {
   const Node* y = &Header;
   const Node* x = Header.Parent;
   
   while (x != 0) 
    if (Compare(Element,((setNode<T>*)x)->Element)<0)
     {y=x; x=x->Left;}
    else
     x=x->Right;
   
   return (Node*)y;
  }

  iterator afterEquals(const T& Element) const
  {
   const Node* y = &Header;
   const Node* x = Header.Parent;
   
   while (x != 0) 
    {
     int c = Compare(Element,((setNode<T>*)x)->Element);
     if (c == 0)
      {y=x; break;}  
     else if (c<0)
      {y=x; x=x->Left;}
     else
      x=x->Right;
    }
   
   return (Node*)y;
  }

  iterator before(const T& Element) const
  {
   const Node* y = &Header;
   const Node* x = Header.Parent;
   
   while (x != 0) 
    if (Compare(Element,((setNode<T>*)x)->Element)<=0)
     {x=x->Left;}
    else
     {y=x; x=x->Right;}
   
   return (Node*)y;
  }

  iterator beforeEquals(const T& Element) const
  {
   const Node* y = &Header;
   const Node* x = Header.Parent;
   
   while (x != 0) 
    {
     int c = Compare(Element,((setNode<T>*)x)->Element);
     if (c == 0)
      {y = x; break;}
     else if (c<0)
      x=x->Left;
     else
      {y=x; x=x->Right;}
    }
   
   return (Node*)y;
  }

  iterator last() {return Header.Right;}

  const_iterator last() const {return Header.Right;}

  unsigned long depth() const {return Depth(Header.Parent);}

 protected:

  void Copy(setNode<T>* Clone)
  {
   if (!Header.Parent) erase();
   if (Clone)
    {
     Copy((setNode<T>*&)Header.Parent,Clone,&Header);
     Header.Left = GetFirst();
     Header.Right = GetLast();
    }
  }

  void Copy(setNode<T>*& RootNode,
            setNode<T>* n,
            const Node* Parent)
  {
   RootNode = new setNode<T>(n->Element,(Node*)Parent);
   RootNode->Balance = n->Balance;

   if (n->Left)
     Copy((setNode<T>*&)RootNode->Left,(setNode<T>*)n->Left,RootNode);
   else RootNode->Left = 0;

   if (n->Right)
     Copy((setNode<T>*&)RootNode->Right,(setNode<T>*)n->Right,RootNode);
   else RootNode->Right = 0;
  }

  Node* GetFirst()
  {
   if (!Header.Parent)
    return &Header;

   else
    {
     Node* SearchNode = Header.Parent;
     while (SearchNode->Left) SearchNode = SearchNode->Left;
     return SearchNode;
    } 
  }      

  Node* GetLast()
  {
   if (!Header.Parent)
    return &Header;

   else
    {
     Node* SearchNode = Header.Parent;
     while (SearchNode->Right) SearchNode = SearchNode->Right;
     return SearchNode;
    } 
  }      

  void Destroy(setNode<T>* RootNode)
  {
    if (RootNode)
    { 
     if (RootNode->Left)
      Destroy((setNode<T>*)RootNode->Left); 

     if (RootNode->Right)
      Destroy((setNode<T>*)RootNode->Right);

     delete RootNode;
    }
  }
};

template<class T>
inline set<T> operator|(const set<T>& a,const set<T>& b)
{set<T> r(a,b,setOperation::Union); return r;}

template<class T>
inline set<T> operator&(const set<T>& a,const set<T>& b)
{set<T> r(a,b,setOperation::Intersection); return r;}

template<class T>
inline set<T> operator^(const set<T>& a,const set<T>& b)
{set<T> r(a,b,setOperation::SymmetricDifference); return r;}

template<class T>
inline set<T> operator-(const set<T>& a,const set<T>& b)
{set<T> r(a,b,setOperation::Difference); return r;}

template<class T>
inline bool operator==(const set<T>& a,const set<T>& b)
{
 set<T>::const_iterator first1 = a.begin();
 set<T>::const_iterator last1  = a.end();
 set<T>::const_iterator first2 = b.begin();
 set<T>::const_iterator last2  = b.end();

 bool equals=true;

 set<T>::keyCompare c = a;

 while (first1 != last1 && first2 != last2)
  {
   int order = c(*first1,*first2);
   if (order < 0)
    {equals=false; break;}
   else if (order > 0)
    {equals=false; break;}
   else
    {++first1; ++first2;}
  }

 if (equals)
  {
   if (first1 != last1) equals = false;
   if (first2 != last2) equals = false;
  }

 return equals;
}

template<class T>
inline bool operator!=(const set<T>& a,const set<T>& b) {return !(a == b);}

template<class T>
inline bool operator<=(const set<T>& a,const set<T>& b)
{
 set<T>::const_iterator first1 = a.begin();
 set<T>::const_iterator last1  = a.end();
 set<T>::const_iterator first2 = b.begin();
 set<T>::const_iterator last2  = b.end();

 set<T>::keyCompare c = a;

 bool subset=true;

 while (first1 != last1 && first2 != last2)
  {
   int order = c(*first1,*first2);
 
   if (order < 0)
    {subset=false; break;}

   else if (order > 0)
    ++first2;
 
   else
    {++first1; ++first2;}
  }

 if (subset) if (first1 != last1) subset = false;

 return subset;
}

template<class T>
inline int compare(const set<T>& a,const set<T>& b)
{
 set<T>::const_iterator first1 = a.begin();
 set<T>::const_iterator last1  = a.end();
 set<T>::const_iterator first2 = b.begin();
 set<T>::const_iterator last2  = b.end();

 set<T>::keyCompare c = a;

 while (first1 != last1 && first2 != last2)
  {
   int order = c(*first1,*first2);
   if (order < 0)
    return -1;
   else if (order > 0)
    return 1;
   else
    {++first1; ++first2;}
  }

 if (first1 != last1) return 1;
 if (first2 != last2) return -1;

 return 0;
}

template<class T>
std::ostream& operator<<(std::ostream& s,const set<T>& o)
{
 s << "{";
 set<T>::const_iterator e = o.end();
 set<T>::const_iterator l = e-1;
 for (set<T>::const_iterator i = o.begin(); i!=e; ++i)
  {s << *i; if (i!=l) s << ",";}
 s << "}";
 return s;
}

void main()
{
 try
  {
   set<double> s;

   //*** Build the Set

   for (int i=0; i<10; i++) s << i+.5;

   //*** Print the set using iterators

   std::cout << "{";

   set<double>::iterator last = s.last();

   for (set<double>::iterator x = s.begin(); x != s.end(); ++x)
    {
        std::cout << *x;
        if (x != last) std::cout << ",";
    }

   std::cout << "}\n";

   //*** Print the set using stream output operator

   std::cout << s << "\n";

   //*** Print the set using for each

   std::cout << "{";

   for each (double d in s)
    {
        std::cout << d;
        if (d != *last) std::cout << ",";
    }

   std::cout << "}\n";
  }
 catch (treeException) {std::cout << "A Tree Exception Occurred.\n";}
}