Ejemplo n.º 1
0
        private static IEnumerable <Tuple <IBinaryTreeNode, TLevel> > LevelOrderTraverse <TLevel>(
            IBinaryTreeNode partialroot,
            TLevel seed,
            Func <TLevel, IBinaryTreeNode, TLevel> leftlevelfunc,
            Func <TLevel, IBinaryTreeNode, TLevel> rightlevelfunc)
        {
            var queue = new Queue <Tuple <IBinaryTreeNode, TLevel> >();

            queue.Enqueue(new Tuple <IBinaryTreeNode, TLevel>(partialroot, seed));
            while (queue.Count > 0)
            {
                var current = queue.Dequeue();
                if (!SentinelEx.EqualNull(current.Item1.LeftChild))
                {
                    queue.Enqueue(new Tuple <IBinaryTreeNode, TLevel>(current.Item1.LeftChild,
                                                                      leftlevelfunc == null ? current.Item2 : leftlevelfunc(current.Item2, partialroot)));
                }
                if (!SentinelEx.EqualNull(current.Item1.RightChild))
                {
                    queue.Enqueue(new Tuple <IBinaryTreeNode, TLevel>(current.Item1.RightChild,
                                                                      rightlevelfunc == null ? current.Item2 : rightlevelfunc(current.Item2, partialroot)));
                }
                yield return(current);
            }
        }
 public bool MoveNext()
 {
     if (_null)
     {
         return(false);
     }
     if (_version != _root.Version)
     {
         throw new InvalidOperationException("在枚举过程中树被修改过");
     }
     if (SentinelEx.EqualNull(_current))
     {
         if (SentinelEx.EqualNull(_root))
         {
             return(false);
         }
         InitPosition();
         return(true);
     }
     return(MoveNextInternal());
 }
Ejemplo n.º 3
0
        public static TreeKind JudgeKind <TNode>(this IRootedTree <TNode> tree)
            where TNode : class, IBinaryTreeNode
        {
            Contract.Requires <ArgumentNullException>(tree != null);
            Contract.Requires <InvalidOperationException>(tree.Root != null, "树不能为空");

            var      last   = tree.Root;
            TreeKind result = TreeKind.Ordinary;

            int  degreelog = tree.Root.GetDegree();
            int  nstrict = 0;
            int  depthlog = -1;
            bool newline = false, completeflag = true;
            Func <int, IBinaryTreeNode, int> updatefunc = (int level, IBinaryTreeNode node) => level + 1;

            foreach (var current in LevelOrderTraverse(tree.Root, 0, updatefunc, updatefunc))
            {
                var node  = current.Item1;
                var depth = current.Item2;
                if (node.GetDegree() != 0)
                {
                    if (node.GetDegree() != degreelog)
                    {
                        nstrict++;
                        if (nstrict > 1)
                        {
                            break;              //more than one inner node differs with root, then it must be a ordinary tree.
                        }
                    }
                }
                else
                {
                    if (depthlog == -1)
                    {
                        depthlog = depth;
                    }
                    else if (depth > depthlog)
                    {
                        if (newline)
                        {
                            completeflag = false;
                        }
                        else
                        {
                            newline = true;
                        }
                    }
                }
                last = node as TNode;
            }
            if (last != tree.Root && SentinelEx.EqualNull(last.Parent.LeftChild))
            {
                completeflag = false;
            }
            if (nstrict == 0)
            {
                if (degreelog == 2)
                {
                    result |= TreeKind.Full;
                }
                else
                {
                    result |= TreeKind.Strict;
                }
            }
            if (nstrict <= 1 && completeflag)
            {
                if (!newline && (last == tree.Root || !SentinelEx.EqualNull(last.Parent.RightChild)))
                {
                    result |= TreeKind.Perfect;
                }
                else
                {
                    result |= TreeKind.Complete;
                }
            }
            return(result);
        }