예제 #1
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);
            }
        }
예제 #2
0
        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));
        }
예제 #3
0
        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);
        }
예제 #4
0
        /// <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);
            }
        }
예제 #5
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);
 }