예제 #1
0
        protected void DoInOrderTraverse(Action <BinaryTreeNodeBase <T> > action)
        {
            BinaryTreeNodeBase <T> node = Root;

            if (node == null)
            {
                return;
            }
            Stack <BinaryTreeNodeBase <T> > stack = new Stack <BinaryTreeNodeBase <T> >();

            while (true)
            {
                while (node != null)
                {
                    stack.Push(node);
                    node = node.Left;
                }
                if (stack.IsEmpty)
                {
                    return;
                }
                action(stack.Peek());
                node = stack.Pop().Right;
            }
        }
예제 #2
0
        protected BinaryTreeNodeBase <T> DoGetDeepestNode()
        {
            BinaryTreeNodeBase <T> node = null;

            DoLevelOrderTraverse((n, level) => { node = n; return(false); });
            return(node);
        }
예제 #3
0
        BinaryTreeNodeBase <T> DoInsertRecursive(BinarySearchTreeNode <T> root, BinaryTreeNodeBase <T> node, Action <T, T> visitAction)
        {
            if (root == null)
            {
                return(node);
            }
            if (visitAction != null)
            {
                visitAction(root.Value, node.Value);
            }
            int comparisonResult = Compare(node.Value, root.Value);

            if (comparisonResult == 0)
            {
                return(root);
            }
            if (comparisonResult < 0)
            {
                root.SetLeft(DoInsertRecursive(root.Left, node, visitAction));
            }
            else
            {
                root.SetRight(DoInsertRecursive(root.Right, node, visitAction));
            }
            return(root);
        }
예제 #4
0
        protected override bool DoDelete(T value)
        {
            bool result = true;
            BinaryTreeNodeBase <T> root = DoDeleteRecursive(value, Root, ref result);

            SetRoot(root);
            return(result);
        }
예제 #5
0
 void DoPreOrderTraverseRecursive(Action <BinaryTreeNodeBase <T> > action, BinaryTreeNodeBase <T> node)
 {
     if (node == null)
     {
         return;
     }
     action(node);
     DoPreOrderTraverseRecursive(action, node.Left);
     DoPreOrderTraverseRecursive(action, node.Right);
 }
        internal static void ExchangeValues(BinaryTreeNodeBase <T> x, BinaryTreeNodeBase <T> y)
        {
            if (x == null || y == null)
            {
                return;
            }
            T temp = x.Value;

            x.value = y.Value;
            y.value = temp;
        }
 internal void RemoveChild(BinaryTreeNodeBase <T> node)
 {
     if (ReferenceEquals(Left, node))
     {
         this.left = null;
     }
     if (ReferenceEquals(Right, node))
     {
         this.right = null;
     }
 }
예제 #8
0
 protected internal bool AreEqual(BinaryTreeNodeBase <T> x, BinaryTreeNodeBase <T> y)
 {
     if (x == null)
     {
         return(y == null);
     }
     if (y == null)
     {
         return(x == null);
     }
     return(AreEqual(x.Value, y.Value));
 }
예제 #9
0
        protected bool DoPostOrderTraverse(Action <BinaryTreeNodeBase <T> > action, Func <bool> traversalFinished = null, Action <BinaryTreeNodeBase <T>, BinaryTreeNodeBase <T>, int> visitingNode = null)
        {
            BinaryTreeNodeBase <T> node = Root;

            if (node == null)
            {
                return(true);
            }
            Stack <BinaryTreeNodeBase <T> > stack = new Stack <BinaryTreeNodeBase <T> >();

            while (true)
            {
                if (node != null)
                {
                    if (visitingNode != null)
                    {
                        visitingNode(node, stack.IsEmpty ? null : stack.Peek(), stack.Size);
                    }
                    stack.Push(node);
                    node = node.Left;
                }
                else
                {
                    if (stack.IsEmpty)
                    {
                        if (traversalFinished != null)
                        {
                            return(traversalFinished());
                        }
                        return(true);
                    }
                    if (stack.Peek().Right == null)
                    {
                        node = stack.Pop();
                        action(node);
                        while (!stack.IsEmpty && node == stack.Peek().Right)
                        {
                            action(node = stack.Pop());
                        }
                    }
                    if (!stack.IsEmpty)
                    {
                        node = stack.Peek().Right;
                    }
                    else
                    {
                        node = null;
                    }
                }
            }
        }
 internal void AddChild(BinaryTreeNodeBase <T> node)
 {
     if (IsFull)
     {
         return;
     }
     if (Left == null)
     {
         this.left = node;
     }
     else
     {
         this.right = node;
     }
 }
예제 #11
0
        int GetTreeWidth(BinaryTreeNodeBase <T> node, ref int result)
        {
            if (node == null)
            {
                return(0);
            }
            int lHeight = GetTreeWidth(node.Left, ref result);
            int rHeight = GetTreeWidth(node.Right, ref result);

            if (lHeight + rHeight + 1 > result)
            {
                result = lHeight + rHeight + 1;
            }
            return(Math.Max(lHeight, rHeight) + 1);
        }
예제 #12
0
        protected BinaryTreeNodeBase <T> DoGetLeastCommonAncestorRecursive(BinaryTreeNodeBase <T> node, BinaryTreeNodeBase <T> x, BinaryTreeNodeBase <T> y)
        {
            if (node == null || ReferenceEquals(node, x) || ReferenceEquals(node, y))
            {
                return(node);
            }
            BinaryTreeNodeBase <T> left  = DoGetLeastCommonAncestor(node.Left, x, y);
            BinaryTreeNodeBase <T> right = DoGetLeastCommonAncestor(node.Right, x, y);

            if (left != null && right != null)
            {
                return(node);
            }
            return(left ?? right);
        }
예제 #13
0
 bool DoGetAncestors(BinaryTreeNodeBase <T> root, BinaryTreeNodeBase <T> node, Stack <BinaryTreeNodeBase <T> > stack)
 {
     if (root == null)
     {
         return(false);
     }
     if (ReferenceEquals(root, node))
     {
         return(true);
     }
     if (DoGetAncestors(root.Left, node, stack) || DoGetAncestors(root.Right, node, stack))
     {
         stack.Push(root);
         return(true);
     }
     return(false);
 }
예제 #14
0
 protected override BinaryTreeNodeBase <T> DoInsert(BinaryTreeNodeBase <T> node, Action <T, T> visitAction)
 {
     Guard.IsNotNull(node, nameof(node));
     if (Root == null)
     {
         SetRoot(node);
         return(node);
     }
     DoLevelOrderTraverse((n, level) => {
         if (!n.IsFull)
         {
             n.AddChild(node);
             return(true);
         }
         return(false);
     });
     return(node);
 }
예제 #15
0
        BinaryTreeNodeBase <T> DoSearchRecursive(BinaryTreeNodeBase <T> root, Func <BinaryTreeNodeBase <T>, int> comparerFunc)
        {
            if (root == null)
            {
                return(null);
            }
            int comparisonResult = comparerFunc(root);

            if (comparisonResult == 0)
            {
                return(root);
            }
            if (comparisonResult > 0)
            {
                return(DoSearchRecursive(root.Left, comparerFunc));
            }
            return(DoSearchRecursive(root.Right, comparerFunc));
        }
예제 #16
0
        protected override bool DoDelete(T value)
        {
            if (Root == null)
            {
                return(false);
            }
            BinaryTreeNodeBase <T> nodeToDelete = null;
            BinaryTreeNodeBase <T> nodeDeepest  = Root;
            BinaryTreeNodeBase <T> itParent     = null;
            int maxLevel = 0;

            return(DoPostOrderTraverse(n => {
                if (nodeToDelete == null && AreEqual(n.Value, value))
                {
                    nodeToDelete = n;
                }
            },
                                       () => {
                if (nodeToDelete == null || nodeDeepest == null)
                {
                    return false;
                }
                if (ReferenceEquals(Root, nodeDeepest))
                {
                    SetRoot(null);
                }
                else
                {
                    BinaryTreeNodeBase <T> .ExchangeValues(nodeDeepest, nodeToDelete);
                    itParent.RemoveChild(nodeDeepest);
                }
                return true;
            },
                                       (n, parent, level) => {
                if (level > maxLevel)
                {
                    nodeDeepest = n;
                    itParent = parent;
                }
            }
                                       ));
        }
예제 #17
0
        protected BinaryTreeNodeBase <T> DoLevelOrderTraverse(Func <BinaryTreeNodeBase <T>, int, bool> predicate)
        {
            if (Root == null)
            {
                return(null);
            }
            int level = 0;
            Queue <BinaryTreeNodeBase <T> > queue = new Queue <BinaryTreeNodeBase <T> >();

            queue.EnQueue(Root);
            queue.EnQueue(null);
            while (!queue.IsEmpty)
            {
                BinaryTreeNodeBase <T> node = queue.DeQueue();
                if (node == null)
                {
                    if (!queue.IsEmpty)
                    {
                        queue.EnQueue(null);
                    }
                    level++;
                }
                else
                {
                    if (predicate(node, level))
                    {
                        return(node);
                    }
                    if (node.Left != null)
                    {
                        queue.EnQueue(node.Left);
                    }
                    if (node.Right != null)
                    {
                        queue.EnQueue(node.Right);
                    }
                }
            }
            return(null);
        }
예제 #18
0
        protected ReadOnlyCollection <BinaryTreeNodeBase <T> > DoGetAncestors(BinaryTreeNodeBase <T> node)
        {
            Guard.IsNotNull(node, nameof(node));
            if (Root == null)
            {
                return(EmptyNodeCollection);
            }
            Stack <BinaryTreeNodeBase <T> > stack = new Stack <BinaryTreeNodeBase <T> >();

            DoGetAncestors(Root, node, stack);
            if (stack.IsEmpty)
            {
                return(EmptyNodeCollection);
            }
            List <BinaryTreeNodeBase <T> > list = new List <BinaryTreeNodeBase <T> >(stack.Size);

            while (!stack.IsEmpty)
            {
                list.Add(stack.Pop());
            }
            return(new ReadOnlyCollection <BinaryTreeNodeBase <T> >(list));
        }
예제 #19
0
        protected override BinaryTreeNodeBase <T> DoGetLeastCommonAncestor(BinaryTreeNodeBase <T> node, BinaryTreeNodeBase <T> x, BinaryTreeNodeBase <T> y)
        {
            BinaryTreeNodeBase <T> n    = node;
            int comparisonResult        = Compare(x.Value, y.Value);
            BinaryTreeNodeBase <T> minN = (comparisonResult > 0 ? y : x);
            BinaryTreeNodeBase <T> maxN = (comparisonResult > 0 ? x : y);

            while (n != null)
            {
                int minCompResult = Compare(n.Value, minN.Value);
                int maxCompResult = Compare(n.Value, maxN.Value);
                if (minCompResult > 0 && maxCompResult < 0)
                {
                    return(n);
                }
                if (maxCompResult == 0)
                {
                    return(maxN);
                }
                n = (minCompResult < 0) ? n.Right : n.Left;
            }
            return(null);
        }
예제 #20
0
        internal ThreadedBinaryTreeNode <T> BuildThreadedTree(BinaryTreeNodeBase <T> root, ThreadedBinaryTreeNode <T> nodeParent, ThreadedBinaryTreeNode <T> nodeRecentVisited)
        {
            if (root == null)
            {
                return(null);
            }
            bool isLeftThreaded              = (root.Left == null);
            bool isRightThreaded             = (root.Right == null);
            ThreadedBinaryTreeNode <T> node  = new ThreadedBinaryTreeNode <T>(root.Value, isLeftThreaded, null, isRightThreaded, null);
            ThreadedBinaryTreeNode <T> left  = BuildThreadedTree(root.Left, node, nodeRecentVisited);
            ThreadedBinaryTreeNode <T> right = BuildThreadedTree(root.Right, nodeParent, node);

            if (isLeftThreaded)
            {
                left = nodeRecentVisited;
            }
            if (isRightThreaded)
            {
                right = nodeParent;
            }
            node.AddChild(left);
            node.AddChild(right);
            return(node);
        }
 internal BinaryTreeNodeBase(T value, BinaryTreeNodeBase <T> left, BinaryTreeNodeBase <T> right)
 {
     this.value = value;
     this.left  = left;
     this.right = right;
 }
 internal void SetLeft(BinaryTreeNodeBase <T> left)
 {
     this.left = left;
 }
예제 #23
0
 protected abstract BinaryTreeNodeBase <T> DoInsert(BinaryTreeNodeBase <T> node, Action <T, T> visitAction);
 internal void SetRight(BinaryTreeNodeBase <T> right)
 {
     this.right = right;
 }
예제 #25
0
 protected virtual BinaryTreeNodeBase <T> DoGetLeastCommonAncestor(BinaryTreeNodeBase <T> node, BinaryTreeNodeBase <T> x, BinaryTreeNodeBase <T> y)
 {
     return(DoGetLeastCommonAncestorRecursive(node, x, y));
 }
예제 #26
0
 protected void SetRoot(BinaryTreeNodeBase <T> root)
 {
     this.root = root;
 }
예제 #27
0
 protected BinaryTreeNodeBase <T> DoGetLeastCommonAncestor(BinaryTreeNodeBase <T> x, BinaryTreeNodeBase <T> y)
 {
     Guard.IsNotNull(x, nameof(x));
     Guard.IsNotNull(y, nameof(y));
     return(DoGetLeastCommonAncestor(Root, x, y));
 }
예제 #28
0
 protected override BinaryTreeNodeBase <T> DoInsert(BinaryTreeNodeBase <T> node, Action <T, T> visitAction)
 {
     return(DoInsertRecursive(Root, (BinarySearchTreeNode <T>)node, visitAction));
 }
예제 #29
0
 public BinaryTreeBase(BinaryTreeNodeBase <T> root)
     : this(root, null)
 {
 }
예제 #30
0
 public BinaryTreeBase(BinaryTreeNodeBase <T> root, IComparer <T> comparer)
 {
     this.root             = root;
     this.comparer         = comparer ?? Comparer <T> .Default;
     this.equalityComparer = EqualityComparer <T> .Default;
 }