递归与非递归两种方式生成树

递归与非递归两种方式生成树

假设有TreeNode类,原始数据类Node,并有数据集:List<Node>  source,现要将其生成树.

    public class TreeNode
    {
        public TreeNode()
        {
            Children = new List<TreeNode>();
        }

        /// <summary>
        /// Id
        /// </summary>
        public int NodeId { get; set; }

        /// <summary>
        /// 父Id
        /// </summary>
        public int? ParentId { get; set; }

        public string Name { get; set; }


        /// <summary>
        /// 是否有下一节点
        /// </summary>
        public bool HasChild
        {
            get { return Children != null && Children.Any(); }
        }

        /// <summary>
        /// 子节点集合
        /// </summary>
        public List<TreeNode> Children { get; set; }


    }
    public class Node
    {
        /// <summary>
        /// Id
        /// </summary>
        public int NodeId { get; set; }

        /// <summary>
        /// 父Id
        /// </summary>
        public int? ParentId { get; set; }

        public string Name { get; set; }
    }

    public class TreeUtils
    {
        /// <summary>
        /// 递归生成树
        /// </summary>
        /// <param name="set">数据源</param>
        /// <returns></returns>
        public static IList<TreeNode> RecursiveCreateTree(List<Node> set)
        {
            var list = new List<TreeNode>();

            List<TreeNode> roots = null;
            roots = set.Where(x => x.ParentId == null || x.ParentId == 0).ToList()
                ?.Select(x =>
                new TreeNode()
                {
                    NodeId = x.NodeId,
                    ParentId = x.ParentId,
                    Name = x.Name,
                }).ToList();
            if (roots == null || !roots.Any())
                return roots;

            var childrenSet = set.Where(x => x.ParentId != null && x.ParentId > 0)?.ToList();
            foreach (var root in roots)
            {
                var children = GetChildren(childrenSet, root.NodeId)?.ToList();
                root.Children = children != null && children.Count > 0 ? children : null;
                list.Add(root);
            }
            return list;
        }
        /// <summary>
        /// 递归方式获取子节点
        /// </summary>
        /// <param name="set">数据源</param>
        /// <param name="parentId">父Id</param>
        /// <returns></returns>
        private static IEnumerable<TreeNode> GetChildren(List<Node> set, int parentId)
        {
            if (set == null || !set.Any())
            {
                yield break;
            }

            var children = set.Where(x => x.ParentId == parentId)?.ToList();
            if (children != null && children.Any())
            {
                foreach (var child in children)
                {
                    TreeNode treeChild = new TreeNode();
                    treeChild.ParentId = parentId;
                    var subChildren = GetChildren(set, child.NodeId)?.ToList();
                    treeChild.Children = subChildren != null && subChildren.Count > 0 ? subChildren : null;
                    yield return treeChild;
                }
            }
            else
            {
                yield break;
            }
        }
        /// <summary>
        /// 非递归方式生成树
        /// </summary>
        /// <param name="set">数据源</param>
        /// <returns></returns>
        public static IList<TreeNode> UnrecursiveCreateTree(List<Node> set)
        {
            List<TreeNode> list = new List<TreeNode>();
            if (set == null || !set.Any()) return list;
            var dic = ToDictionary(set);
            foreach (var pair in dic)
            {
                var pid = pair.Value.ParentId;
                if (!pid.HasValue || pid == 0)
                {
                    list.Add(pair.Value);
                    continue;
                }
                if (pid.HasValue && dic.ContainsKey(pid.Value))
                {
                    dic[pid.Value].Children.Add(pair.Value);
                }
            }
            return list;
        }
        /// <summary>
        /// 转成字典
        /// </summary>
        /// <param name="set">数据源</param>
        /// <returns></returns>
        private static Dictionary<int, TreeNode> ToDictionary(List<Node> set)
        {
            var list = new Dictionary<int, TreeNode>();
            if (set == null || !set.Any()) return list;
            foreach (var node in set)
            {
                var model = new TreeNode
                {
                    NodeId = node.NodeId,
                    ParentId = node.ParentId,
                    Name = node.Name,
                };
                list.Add(model.NodeId, model);
            }
            return list;
        }


    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值