C# 通用树形数据结构

前言

    树在图论中是一种重要的图,由于其自身的许多特殊性质,也是一种重要的计算机数据结构,在很多地方都有用。但是这些树大多都是作为其他应用的内部数据结构来使用。我们无法了解这些树的详细信息,而 .Net 也没有在内置的集合类库中提供树形数据结构的类。很多时候我们都需要树形数据完成一些工作,在自己的实践经验和查阅大量相关资料后,我编写了一个使用简单,能方便地将普通集合转换为树形集合(当然前提是这些集合元素之间存在能够表明层级关系的数据),提供了大量图论中有关节点和整棵树的信息和常用算法的通用树形数据结构类。希望能够简化此类需求的开发。

正文

    图论中有关树的定义和性质都能很容易查到资料,就不再啰嗦,进入正题。首先,定义一个树形结构有很多方法,在此我选用最直观的双亲孩子表示法定义。为了能将包含层级信息的普通数据转换为树形数据,使用接口进行定义,并以接口为核心进行扩展。接口定义如下:

 1     /// <summary>
 2     /// 可分层数据接口
 3     /// </summary>
 4     /// <typeparam name="T">数据类型</typeparam>
 5     public interface IHierarchical<out T>
 6     {
 7         /// <summary>
 8         /// 当前节点的数据
 9         /// </summary>
10         T Current { get; }
11 
12         /// <summary>
13         /// 根节点
14         /// </summary>
15         IHierarchical<T> Root { get; }
16 
17         /// <summary>
18         /// 双亲(父)节点
19         /// </summary>
20         IHierarchical<T> Parent { get; }
21 
22         /// <summary>
23         /// 祖先节点集合(按路径距离升序)
24         /// </summary>
25         IEnumerable<IHierarchical<T>> Ancestors { get; }
26 
27         /// <summary>
28         /// 子节点集合
29         /// </summary>
30         IEnumerable<IHierarchical<T>> Children { get; }
31 
32         /// <summary>
33         /// 后代节点集合(深度优先先序遍历)
34         /// </summary>
35         IEnumerable<IHierarchical<T>> Descendants { get; }
36 
37         /// <summary>
38         /// 兄弟节点集合(不包括自身节点)
39         /// </summary>
40         IEnumerable<IHierarchical<T>> Siblings { get; }
41 
42         /// <summary>
43         /// 在兄弟节点中的排行
44         /// </summary>
45         int IndexOfSiblings { get; }
46 
47         /// <summary>
48         /// 节点的层
49         /// </summary>
50         int Level { get; }
51 
52         /// <summary>
53         /// 节点(以当前节点为根的子树)的高度
54         /// </summary>
55         int Height { get; }
56 
57         /// <summary>
58         /// 节点的度
59         /// </summary>
60         int Degree { get; }
61 
62         /// <summary>
63         /// 树(以当前节点为根的子树)的所有节点中度最大的节点的度
64         /// </summary>
65         int MaxDegreeOfTree { get; }
66 
67         /// <summary>
68         /// 当前节点是否是根节点
69         /// </summary>
70         bool IsRoot { get; }
71 
72         /// <summary>
73         /// 当前节点是否是叶子节点
74         /// </summary>
75         bool IsLeaf { get; }
76 
77         /// <summary>
78         /// 当前节点是否有子节点
79         /// </summary>
80         bool HasChild { get; }
81 
82         /// <summary>
83         /// 以当前节点为根返回树形排版的结构字符串
84         /// </summary>
85         /// <param name="formatter">数据对象格式化器(内容要为一行,否则会影响排版)</param>
86         /// <param name="convertToSingleLine">处理掉换行符变成单行文本</param>
87         /// <returns></returns>
88         string ToString(Func<T, string> formatter, bool convertToSingleLine = false);
89     }

    然后根据接口定义扩展类型。实现如下:

  1     /// <summary>
  2     /// 可分层数据扩展
  3     /// </summary>
  4     public static class HierarchicalExtensions
  5     {
  6         /// <summary>
  7         /// 转换为可分层数据
  8         /// </summary>
  9         /// <typeparam name="T">数据类型</typeparam>
 10         /// <param name="item">数据</param>
 11         /// <param name="childSelector">下层数据选择器</param>
 12         /// <returns>已分层的数据</returns>
 13         public static IHierarchical<T> AsHierarchical<T>(this T item, Func<T, IEnumerable<T>> childSelector)
 14         {
 15             return new Hierarchical<T>(item, childSelector);
 16         }
 17 
 18         /// <summary>
 19         /// 分层数据
 20         /// </summary>
 21         /// <typeparam name="T">数据类型</typeparam>
 22         private class Hierarchical<T> : IHierarchical<T>
 23         {
 24             private readonly object _locker;
 25             private readonly Func<T, IEnumerable<T>> _childSelector;
 26             private IEnumerable<IHierarchical<T>> _children;
 27 
 28             /// <summary>
 29             /// 实例化分层数据
 30             /// </summary>
 31             /// <param name="item">数据</param>
 32             /// <param name="childSelector">下层数据选择器</param>
 33             public Hierarchical(T item, Func<T, IEnumerable<T>> childSelector)
 34             {
 35                 _locker = new ob
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值