protected override void OnNodeBegin(WalkChanceAndActionTreesContext[] stack, int depth) { WalkChanceAndActionTreesContext context = stack[depth]; TreeKind treeKind = context.TreeKind; string line = String.Format("B tree:{0} node:{1} depth:{2}\r\n", treeKind, context.NodeIdx[(int)treeKind], depth); Text += line; // Console.Write(line); BeginCount[(int)treeKind]++; }
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); }