Esempio n. 1
0
        public static int GetDegree(this IBinaryTreeNode node)
        {
            Contract.Requires <ArgumentNullException>(node != null);
            Contract.Ensures(Contract.Result <int>() >= 0 && Contract.Result <int>() <= 2);

            if (SentinelEx.NotEqualNull(node.LeftChild))
            {
                if (SentinelEx.NotEqualNull(node.RightChild))
                {
                    return(2);
                }
                else
                {
                    return(1);
                }
            }
            else if (SentinelEx.NotEqualNull(node.RightChild))
            {
                return(1);
            }
            else
            {
                return(0);
            }
        }
Esempio n. 2
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);
            }
        }
Esempio n. 3
0
        private static IEnumerable <Tuple <IMultiwayTreeNode, TLevel> > LevelOrderTraverse <TLevel>(
            IMultiwayTreeNode partialroot,
            TLevel seed,
            Func <TLevel, IMultiwayTreeNode, int, TLevel> levelfunc)
        {
            var queue = new Queue <Tuple <IMultiwayTreeNode, TLevel> >();

            queue.Enqueue(new Tuple <IMultiwayTreeNode, TLevel>(partialroot, seed));
            int index;

            while (queue.Count > 0)
            {
                index = 0;
                var current = queue.Dequeue();
                if (SentinelEx.NotEqualNull(current.Item1.Children))
                {
                    foreach (var node in current.Item1.Children)
                    {
                        queue.Enqueue(new Tuple <IMultiwayTreeNode, TLevel>(node,
                                                                            levelfunc == null ? current.Item2 : levelfunc(current.Item2, partialroot, index++)));
                    }
                }
                yield return(current);
            }
        }
 protected override bool MoveNextInternal()
 {
     if (SentinelEx.NotEqualNull(_current.RightChild))
     {
         _stack.Push(_current);
         _current = _current.RightChild as TNode;
         while (SentinelEx.NotEqualNull(_current.LeftChild))
         {
             _stack.Push(_current);
             _current = _current.LeftChild as TNode;
         }
         return(true);
     }
     else
     {
         while (_stack.Count > 0 && _stack.Peek().RightChild == _current)
         {
             _current = _stack.Pop(); //向上找到右行点
         }
         if (_stack.Count == 0)
         {
             return(false);
         }
         _current = _stack.Pop();
         return(true);
     }
 }
 protected override void InitPosition()
 {
     _current = _root;
     while (SentinelEx.NotEqualNull(_current.LeftChild))
     {
         _stack.Push(_current);
         _current = _current.LeftChild as TNode;
     }
 }
 internal RecursiveEnumerator(TNode root)
 {
     if (SentinelEx.NotEqualNull(root))
     {
         _root    = root;
         _version = root.Version;
         _stack   = new Stack <TNode>();
     }
     else
     {
         _null = true;
     }
 }
Esempio n. 7
0
        public static bool IsAncestorOf(this BinaryTreeNode node, BinaryTreeNode target)
        {
            Contract.Requires <ArgumentNullException>(node != null);
            Contract.Requires <ArgumentNullException>(target != null);

            var p = target.Parent;

            while (SentinelEx.NotEqualNull(p))
            {
                if (p == node)
                {
                    return(true);
                }
                p = p.Parent;
            }
            return(false);
        }
 protected override bool MoveNextInternal()
 {
     if (SentinelEx.NotEqualNull(_current.RightChild))
     {
         _stack.Push(_current.RightChild as TNode);
     }
     if (SentinelEx.NotEqualNull(_current.LeftChild))
     {
         _current = _current.LeftChild as TNode;
         return(true);
     }
     if (_stack.Count == 0)
     {
         return(false);
     }
     _current = _stack.Pop();
     return(true);
 }
 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());
 }
 public bool MoveNext()
 {
     if (_version != _root.Version)
     {
         throw new InvalidOperationException("在枚举过程中树被修改过");
     }
     if (_queue.Count == 0)
     {
         return(false);
     }
     _current = _queue.Dequeue();
     if (SentinelEx.NotEqualNull(_current.LeftChild))
     {
         _queue.Enqueue(_current.LeftChild as TNode);
     }
     if (SentinelEx.NotEqualNull(_current.RightChild))
     {
         _queue.Enqueue(_current.RightChild as TNode);
     }
     return(true);
 }
 protected override bool MoveNextInternal()
 {
     if (_stack.Count == 0)
     {
         return(false);
     }
     if (_stack.Peek().LeftChild != _current && _stack.Peek().RightChild != _current)
     {
         TNode temp = _stack.Peek();
         while (SentinelEx.NotEqualNull(temp))
         {
             if (SentinelEx.NotEqualNull(temp.LeftChild))
             {
                 if (SentinelEx.NotEqualNull(temp.RightChild))
                 {
                     _stack.Push(temp.RightChild as TNode);
                 }
                 _stack.Push(temp.LeftChild as TNode);
             }
             else
             {
                 if (SentinelEx.NotEqualNull(temp.RightChild))
                 {
                     _stack.Push(temp.RightChild as TNode);
                 }
                 else
                 {
                     break;
                 }
             }
             temp = _stack.Peek();
         }
     }
     _current = _stack.Pop();
     return(true);
 }
Esempio n. 12
0
 public static int GetDegree(this IMultiwayTreeNode node)
 {
     Contract.Requires <ArgumentNullException>(node == null);
     Contract.Ensures(Contract.Result <int>() >= 0);
     return(node.Children?.Count(cnode => SentinelEx.NotEqualNull(cnode)) ?? 0);
 }
Esempio n. 13
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);
        }