示例#1
0
        private static IEnumerable <T> TraverseTree <T>(T root, Func <T, T> getLeftChild, Func <T, T> getRightChild, Func <T, T> getParent, TraversalKind traversalKind)
            where T : class
        {
            if (root == null)
            {
                throw new ArgumentNullException(nameof(root));
            }
            if (getLeftChild == null)
            {
                throw new ArgumentNullException(nameof(getLeftChild));
            }
            if (getRightChild == null)
            {
                throw new ArgumentNullException(nameof(getRightChild));
            }
            if (getParent == null)
            {
                throw new ArgumentNullException(nameof(getParent));
            }

            T previous = getParent(root);
            T current  = root;

            while (current != null)
            {
                if (previous == getParent(current))
                {
                    if (traversalKind == TraversalKind.PreOrder)
                    {
                        yield return(current);
                    }

                    T left = getLeftChild(current);

                    if (left == null)
                    {
                        previous = left;
                    }
                    else
                    {
                        previous = current;
                        current  = left;
                        continue;
                    }
                }

                if (previous == getLeftChild(current))
                {
                    if (traversalKind == TraversalKind.InOrder)
                    {
                        yield return(current);
                    }

                    T right = getRightChild(current);

                    if (right == null)
                    {
                        previous = right;
                    }
                    else
                    {
                        previous = current;
                        current  = right;
                        continue;
                    }
                }

                if (previous == getRightChild(current))
                {
                    if (traversalKind == TraversalKind.PostOrder)
                    {
                        yield return(current);
                    }

                    previous = current;
                    current  = getParent(current);
                }
            }
        }
示例#2
0
        public void Traversal(char root, TraversalKind kind, string expected)
        {
            var actual = new string(root.Traverse(GetChildren, kind).ToArray());

            Assert.AreEqual(expected, actual);
        }
        /// <summary>
        /// Perform traversal of basic Tree-like structures or Graphs without cycles.
        /// Asymptotic worst case: O(n)
        /// Memory asymptotic worst case: O(n)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="root">Starting subtree root.</param>
        /// <param name="childrenProvider">Children provider for each node.</param>
        /// <param name="kind">Traversal algorithm to use.</param>
        /// <returns></returns>
        public static IEnumerable <T> Traverse <T>(this T root, Func <T, IEnumerable <T> > childrenProvider, TraversalKind kind = default(TraversalKind))
        {
            if (childrenProvider == null)
            {
                throw new ArgumentNullException(nameof(childrenProvider));
            }
            switch (kind)
            {
            case TraversalKind.ReverseInOrder:
                return(root.TraverseReverseInOrder(childrenProvider));

            case TraversalKind.PreOrder:
                return(root.TraversePreOrder(childrenProvider));

            case TraversalKind.PostOrder:
                return(root.TraversePostOrder(childrenProvider));

            case TraversalKind.LevelOrder:
                return(root.TraverseLevelOrder(childrenProvider));
            }
            throw new NotImplementedException(kind.ToString());
        }