public pcnPair <T> DeleteRightMinKeyNode()
 {
     if (IsRightEmpty())
     {
         throw new SBTNodeEmptyException(true);
     }
     if (this.Right.IsLeftEmpty())
     {
         BinarySearchTreeNode <T> buf = this.Right;
         this.ChangeRightSubtree(buf.Right);
         return(new pcnPair <T>(this, buf));
     }
     else
     {
         pcnPair <T> rmnPair = GetRightMinKeyNodePair();
         if (rmnPair.cNode.IsRightEmpty())
         {
             rmnPair.pNode.RemoveLeftSubtree(); return(rmnPair);
         }
         else
         {
             rmnPair.pNode.ChangeLeftSubtree(rmnPair.cNode.Right); return(rmnPair);
         }
     }
 }
            public BinarySearchTreeNode <T> RemoveNode(U targetkey)
            {
                if (_rtnd == null)
                {
                    throw new NotFound();
                }
                BinarySearchTreeNode <T> vNode = new BinarySearchTreeNode <T>(_rtnd.Data, null, _rtnd); //virtual node that is the parent of root node;
                pcnPair <T> delPair            = SearchPair(targetkey, vNode);

                if (delPair.cNode.IsTerminal())
                {
                    if (delPair.pNode.Left == delPair.cNode)
                    {
                        return((BinarySearchTreeNode <T>)delPair.pNode.RemoveLeftSubtree());
                    }
                    else
                    {
                        return((BinarySearchTreeNode <T>)delPair.pNode.RemoveRightSubtree());
                    }
                }
                else if (delPair.cNode.IsLeftEmpty())
                {
                    delPair.cNode.Data = delPair.cNode.DeleteRightMinKeyNode().cNode.Data;
                }
                else
                {
                    delPair.cNode.Data = delPair.cNode.DeleteLeftMaxKeyNode().cNode.Data;
                }
                _rtnd = vNode.Right;
                vNode.Dispose();
                return(delPair.cNode);
            }
 public pcnPair <T> DeleteLeftMaxKeyNode()
 {
     if (IsLeftEmpty())
     {
         throw new SBTNodeEmptyException(false);
     }
     if (this.Left.IsRightEmpty())
     {
         BinarySearchTreeNode <T> buf = this.Left;
         this.ChangeLeftSubtree(buf.Left);
         return(new pcnPair <T>(this, buf));
     }
     else
     {
         pcnPair <T> lmnPair = GetLeftMaxKeyNodePair();
         if (lmnPair.cNode.IsLeftEmpty())
         {
             lmnPair.pNode.RemoveRightSubtree(); return(lmnPair);
         }
         else
         {
             lmnPair.pNode.ChangeRightSubtree(lmnPair.cNode.Left); return(lmnPair);
         }
     }
 }
            public pcnPair <T> SearchPair(U targetkey, BinarySearchTreeNode <T> vNode)
            {
                BinarySearchTreeNode <T> parent = vNode;
                BinarySearchTreeNode <T> child  = _rtnd;
                U ckey;

                while (child != null)
                {
                    ckey = _gkey(child.Data);
                    if (targetkey.CompareTo(ckey) < 0)
                    {
                        parent = child; child = parent.Left;
                    }
                    else if (targetkey.CompareTo(ckey) > 0)
                    {
                        parent = child; child = parent.Right;
                    }
                    else
                    {
                        pcnPair <T> r = new pcnPair <T>(parent, child);
                        return(r);
                    }
                }
                throw new NotFound();
            }