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()); }
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); }