当前位置:编程学习 > C#/ASP.NET >>

C#中一种通用的树的生成方式

 

在写程序时,经常要用到树的这种结构,如果是做界面编程,那么TreeView是一个不错的选择,几个设置就能把数据绑定好,但是如果自己写类呢?相对就麻烦一点。

 

这里讨论一下如何快速建立自己的树型结构,即怎么把建树的方法抽离出来加以复用。

 

代码的复用,不外乎类,接口,泛型。

 

先考虑用接口来实现,定义一个ITreeNode 然后每一个要建立树型结构的结点去实现?感觉不大好,因为你要定义比如Parent Children等一系列的东西,很是很麻烦,每一个实现起来也很困难。

 

那抽像类?抽象类的继承到是方便,但是在实际使用中涉及各种类型转换,代码写起来不爽。

 

泛型呢?泛型的结构又过于笼统 ,但是可以折衷一下,就是用泛型定义一个结点的类

 

(小弟写代码方式都相对“妥协”,一位大人说的,各位将就着看哈)

 

 

 

 1 namespace Soway.DB.Tree

 2 {

 3     public class  TreeNode<T>

 4     {

 5

 6         public T Data { get; set; }

 7         public TreeNode<T> Parent { get; set; }

 8         public List<TreeNode<T>> Children { get; set; }

 9     }

10 }

 

 

 

结点类定义好了以后,就要去实现一个TreeFactory ,将建树的通用算法提出来。

 

 

 

namespace Soway.DB.Tree

{

 

   

   

    public class TreeFactory <T>

    {

public List<TreeNode<T>> CreateTreeByLevel

            (List<T> Items )

        {

            //////

        }

    }

}

 

这里的我的方法名已经默认为ByLevel ,即按层建立树,这样,新的问题又出现了:

 

1.怎么保证输入值Items是已经按层遍立建立好的结点?

 

2.怎么分层?即怎么区分树的父结点,子结点,同级结点之间的关系 ?

 

这些问题其实都与泛型的具体类型有关,但如果把具体类型约束了,那就违反我们本意了。

 

走一步算一步,先这样,把树结点之间的关系定义出来,算是一个枚举吧:

 

 

 

namespace Soway.DB.Tree

{

    public enum  TeeNodeCompareResult

    {

        /// <summary>

        /// 树结点

        /// </summary>

        Parent,

        /// <summary>

        /// 子结点

        /// </summary>

        Child,

        /// <summary>

        /// 下一个同级结点

        /// </summary>

        NextNode,

        /// <summary>

        /// 前一个同级结点

        /// </summary>

        PreNode,

        /// <summary>

        /// 同一个结点

        /// </summary>

        EquealNode ,

        /// <summary>

        /// 下一层的结点

        /// </summary>

        NexLevelNode

 

    }

}

 

 

 

有了这个关系以后,于是有了进一步的想法,考虑传递给TreeFactory一个委托,可以通过这个来得到两个结点之间比较关系:

 

 

 

namespace Soway.DB.Tree

{

    public delegate TeeNodeCompareResult TeeNodeCompare<T>(T child, T parent);

}

 

这样,我们的TreeFactory里多了一个泛型委托的成员。。。

 

 

 

   private TeeNodeCompare<T> compare;

 

        public TreeFactory(Tree.TeeNodeCompare<T> Compare)

        {

            this.compare = Compare;

 

        }

 

 

 

现在,当这个泛型委托处理好了以后,我们下一步问题也好办了,就是将输入的Items进行按层排序,这时,只要有一个Comparison<T>()的实现 ,我直接调用List<T>.Sort(Comprarion<T>)即可了

 

下面给出这个Comparation<T>的实现 :

 

 

 

 private int CompareResult(T ob1, T ob2)

        {

            switch (compare(ob1, ob2))

            {

                case TeeNodeCompareResult.Child:

                case TeeNodeCompareResult.NextNode:

                case TeeNodeCompareResult.NexLevelNode:

                    return 1;

                case TeeNodeCompareResult.Parent :

                case TeeNodeCompareResult.PreNode:

                    return -1;

                default :

                    return 0;

            }

         

                

        }

 

好,这些基础工作做完以后,建树的就容易了:

 

 

 

      /// <summary>

        /// 按层建立树

        /// </summary>

 

补充:软件开发 , C# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,