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); } }
public static IEnumerable <IMultiwayTreeNode> TraverseSubtree(this IMultiwayTreeNode partialroot, TraverseOrder order = TraverseOrder.LevelOrder) { Contract.Requires <ArgumentNullException>(partialroot != null); Contract.Requires <NotSupportedException>(order != TraverseOrder.InOrder, "多叉树不支持中序遍历"); Contract.Ensures(Contract.Result <IEnumerable <IMultiwayTreeNode> >() != null); return(partialroot.TraverseSubtree <object>(null, null, order).Select(res => res.Item1)); }
private static bool AreChildrenLeftPadding(this IMultiwayTreeNode node) { if (node.Children == null) { return(true); } bool flag = true; foreach (var t in node.Children) { if (t != null && !flag) { return(false); } else { flag = false; } } return(true); }
/// <summary> /// enumerate the subtree with the root <paramref name="partialroot"/>, provided with certain information (of type <typeparamref name="TLevel"/>) of the node /// 遍历以<paramref name="partialroot"/>为根的子树,并且在过程中提供结点有关信息(<typeparamref name="TLevel"/>类型的) /// </summary> /// <typeparam name="TLevel">提供的每层结点额外信息的类型</typeparam> /// <param name="partialroot">需要遍历的子树的根</param> /// <param name="seed">附加参数的初始值</param> /// <param name="levelfunc">遍历到某一层结点时将附加参数传给下一层孩子时需要进行的操作。第一个参数是该层的附加参数, /// 第二个参数是遍历到的结点,第三个是遍历到的结点在上层结点孩子结点中的编号</param> /// <param name="order">多叉树遍历方式</param> /// <returns>遍历得到的结点与附加参数的集合</returns> public static IEnumerable <Tuple <IMultiwayTreeNode, TLevel> > TraverseSubtree <TLevel>( this IMultiwayTreeNode partialroot, TLevel seed, Func <TLevel, IMultiwayTreeNode, int, TLevel> levelfunc, TraverseOrder order = TraverseOrder.LevelOrder) { Contract.Requires <ArgumentNullException>(partialroot != null); Contract.Requires <NotSupportedException>(order != TraverseOrder.InOrder, "多叉树不支持中序遍历"); Contract.Ensures(Contract.Result <IEnumerable <Tuple <IMultiwayTreeNode, TLevel> > >() != null); var current = new Tuple <IMultiwayTreeNode, TLevel>[] { new Tuple <IMultiwayTreeNode, TLevel>(partialroot, seed) }; switch (order) { case TraverseOrder.PreOrder: return(current.Concat(partialroot.Children? .SelectMany((node, index) => node?.TraverseSubtree( levelfunc == null ? seed : levelfunc(seed, partialroot, index), levelfunc, order) ?? Enumerable.Empty <Tuple <IMultiwayTreeNode, TLevel> >()) ?? Enumerable.Empty <Tuple <IMultiwayTreeNode, TLevel> >())); case TraverseOrder.PostOrder: return((partialroot.Children? .SelectMany((node, index) => node?.TraverseSubtree( levelfunc == null ? seed : levelfunc(seed, partialroot, index), levelfunc, order) ?? Enumerable.Empty <Tuple <IMultiwayTreeNode, TLevel> >()) ?? Enumerable.Empty <Tuple <IMultiwayTreeNode, TLevel> >()) .Reverse().Concat(current)); case TraverseOrder.LevelOrder: return(LevelOrderTraverse(partialroot, seed, levelfunc)); default: return(null); } }
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); }