private void PostOrderTraverse(Y2BinaryTreeNode <T> node)
 {
     if (node == null)
     {
         return;
     }
     PostOrderTraverse(node.LeftChild);
     PostOrderTraverse(node.RightChild);
     _list.Add(node.Value);
 }
 private int GetHeight(Y2BinaryTreeNode <T> startNode)
 {
     if (startNode == null)
     {
         return(0);
     }
     else
     {
         return(1 + Math.Max(GetHeight(startNode.LeftChild), GetHeight(startNode.RightChild)));
     }
 }
        public virtual bool Add(T value)
        {
            Y2BinaryTreeNode <T> node = new Y2BinaryTreeNode <T>(value);

            if (Root == null)
            {
                Count++;
                Root = node;
                return(true);
            }

            return(Add(Root, node));
        }
 public virtual void ClearChildren(Y2BinaryTreeNode <T> node)
 {
     if (node.HasLeftChild)
     {
         ClearChildren(node.LeftChild);
         node.LeftChild.Parent = null;
         node.LeftChild        = null;
     }
     if (node.HasRightChild)
     {
         ClearChildren(node.RightChild);
         node.RightChild.Parent = null;
         node.RightChild        = null;
     }
 }
        public virtual Queue <T> FindPath(T value)
        {
            Queue <T> q = new Queue <T>();

            Y2BinaryTreeNode <T> node = this.Root;
            bool isFounded            = false;

            while (node != null)
            {
                if (node.Value.Equals(value))
                {
                    isFounded = true;
                    break;
                }
                else
                {
                    if (node.Value.CompareTo(value) > 0)
                    {
                        node = node.LeftChild;
                    }
                    else
                    {
                        node = node.RightChild;
                    }

                    if (node != null)
                    {
                        q.Enqueue(node.Value);
                    }
                }
            }
            if (!isFounded)
            {
                q.Clear();
                q = null;
            }

            return(q);
        }
        public virtual Y2BinaryTreeNode <T> Search(Y2BinaryTreeNode <T> node, T value)
        {
            if (node == null)
            {
                return(null);
            }

            if (node.Value.Equals(value))
            {
                return(node);
            }
            else
            {
                if (node.Value.CompareTo(value) > 0)
                {
                    return(Search(node.LeftChild, value));
                }
                else
                {
                    return(Search(node.RightChild, value));
                }
            }
        }
        private bool Add(Y2BinaryTreeNode <T> parentNode, Y2BinaryTreeNode <T> node)
        {
            if (parentNode.Value.Equals(node.Value))
            {
                return(false);
            }

            if (parentNode > node)
            {
                if (!parentNode.HasLeftChild)
                {
                    parentNode.LeftChild = node;
                    node.Parent          = parentNode;
                    Count++;
                    return(true);
                }
                else
                {
                    return(Add(parentNode.LeftChild, node));
                }
            }
            else
            {
                if (!parentNode.HasRightChild)
                {
                    parentNode.RightChild = node;
                    node.Parent           = parentNode;
                    Count++;
                    return(true);
                }
                else
                {
                    return(Add(parentNode.RightChild, node));
                }
            }
        }
        public int CompareTo(object obj)
        {
            Y2BinaryTreeNode <T> node = obj as Y2BinaryTreeNode <T>;

            return(this.Value.CompareTo(node.Value));
        }
        private bool Remove(Y2BinaryTreeNode <T> node, T value)
        {
            if (node == null)
            {
                return(false);
            }

            if (node.Value.Equals(value))
            {
                if (node.IsLeaf) // no children
                {
                    if (node.Parent.LeftChild == node)
                    {
                        node.Parent.LeftChild = null;
                    }
                    else
                    {
                        node.Parent.RightChild = null;
                    }

                    node.Parent = null;
                }
                else if (node.HasLeftChild && node.HasRightChild)   // 2 children
                {
                    // Tìm successor node
                    Y2BinaryTreeNode <T> replacementNode = node.RightChild;

                    while (replacementNode.HasLeftChild)
                    {
                        replacementNode = replacementNode.LeftChild;
                    }
                    node.Value = replacementNode.Value;

                    Remove(replacementNode, replacementNode.Value);
                }
                else    // one child
                {
                    Y2BinaryTreeNode <T> subNode;

                    if (node.HasLeftChild)
                    {
                        subNode = node.LeftChild;
                    }
                    else
                    {
                        subNode = node.RightChild;
                    }

                    if (Root == (subNode))
                    {
                        Root = subNode;
                    }

                    subNode.Parent = node.Parent;

                    if (node.Parent.LeftChild == node)
                    {
                        node.Parent.LeftChild = subNode;
                    }
                    else
                    {
                        node.Parent.RightChild = subNode;
                    }
                }
                Count--;
                return(true);
            }
            else
            {
                if (node.Value.CompareTo(value) > 0)
                {
                    return(Remove(node.LeftChild, value));
                }
                else
                {
                    return(Remove(node.RightChild, value));
                }
            }
        }