国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

C#中一種通用的樹的生成方式

2019-11-06 06:16:46
字體:
供稿:網(wǎng)友

在寫程序時(shí),經(jīng)常要用到樹的這種結(jié)構(gòu),如果是做界面編程,那么TreeView是一個(gè)不錯(cuò)的選擇,幾個(gè)設(shè)置就能把數(shù)據(jù)綁定好,但是如果自己寫類呢?相對(duì)就麻煩一點(diǎn)。

這里討論一下如何快速建立自己的樹型結(jié)構(gòu),即怎么把建樹的方法抽離出來加以復(fù)用。

代碼的復(fù)用,不外乎類,接口,泛型。

先考慮用接口來實(shí)現(xiàn),定義一個(gè)ITreeNode 然后每一個(gè)要建立樹型結(jié)構(gòu)的結(jié)點(diǎn)去實(shí)現(xiàn)?感覺不大好,因?yàn)槟阋x比如Parent Children等一系列的東西,很是很麻煩,每一個(gè)實(shí)現(xiàn)起來也很困難。

那抽像類?抽象類的繼承到是方便,但是在實(shí)際使用中涉及各種類型轉(zhuǎn)換,代碼寫起來不爽。

泛型呢?泛型的結(jié)構(gòu)又過于笼統(tǒng) ,但是可以折衷一下,就是用泛型定義一個(gè)結(jié)點(diǎn)的類

(小弟寫代碼方式都相對(duì)“妥協(xié)”,一位大人說的,各位將就著看哈)

 

復(fù)制代碼 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 }復(fù)制代碼

 

結(jié)點(diǎn)類定義好了以后,就要去實(shí)現(xiàn)一個(gè) TreeFactory ,將建樹的通用算法提出來。

 

復(fù)制代碼namespace Soway.DB.Tree{            public class TreeFactory <T>    { public List<TreeNode<T>> CreateTreeByLevel            (List<T> Items )        {            //////        }    }}復(fù)制代碼

這里的我的方法名已經(jīng)默認(rèn)為ByLevel ,即按層建立樹,這樣,新的問題又出現(xiàn)了:

1.怎么保證輸入值Items是已經(jīng)按層遍立建立好的結(jié)點(diǎn)?

2.怎么分層?即怎么區(qū)分樹的父結(jié)點(diǎn),子結(jié)點(diǎn),同級(jí)結(jié)點(diǎn)之間的關(guān)系 ?

這些問題其實(shí)都與泛型的具體類型有關(guān),但如果把具體類型約束了,那就違反我們本意了。

走一步算一步,先這樣,把樹結(jié)點(diǎn)之間的關(guān)系定義出來,算是一個(gè)枚舉吧:

 

復(fù)制代碼namespace Soway.DB.Tree{    public enum  TeeNodeCompareResult    {        /// <summary>        /// 樹結(jié)點(diǎn)        /// </summary>        Parent,        /// <summary>        /// 子結(jié)點(diǎn)        /// </summary>        Child,        /// <summary>        /// 下一個(gè)同級(jí)結(jié)點(diǎn)        /// </summary>        NextNode,        /// <summary>        /// 前一個(gè)同級(jí)結(jié)點(diǎn)        /// </summary>        PReNode,        /// <summary>        /// 同一個(gè)結(jié)點(diǎn)        /// </summary>        EquealNode ,        /// <summary>        /// 下一層的結(jié)點(diǎn)        /// </summary>        NexLevelNode    }}復(fù)制代碼

 

有了這個(gè)關(guān)系以后,于是有了進(jìn)一步的想法,考慮傳遞給TreeFactory一個(gè)委托,可以通過這個(gè)來得到兩個(gè)結(jié)點(diǎn)之間比較關(guān)系:

 

namespace Soway.DB.Tree{    public delegate TeeNodeCompareResult TeeNodeCompare<T>(T child, T parent);}

這樣,我們的TreeFactory里多了一個(gè)泛型委托的成員。。。

 

復(fù)制代碼   private TeeNodeCompare<T> compare;        public TreeFactory(Tree.TeeNodeCompare<T> Compare)        {            this.compare = Compare;        }復(fù)制代碼

 

現(xiàn)在,當(dāng)這個(gè)泛型委托處理好了以后,我們下一步問題也好辦了,就是將輸入的Items進(jìn)行按層排序,這時(shí),只要有一個(gè)Comparison<T>()的實(shí)現(xiàn) ,我直接調(diào)用 List<T>.Sort(Comprarion<T>)即可了

下面給出這個(gè)Comparation<T>的實(shí)現(xiàn) :

 

復(fù)制代碼 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;            }                                  }復(fù)制代碼

好,這些基礎(chǔ)工作做完以后,建樹的就容易了:

 

復(fù)制代碼      /// <summary>        /// 按層建立樹        /// </summary>        /// <param name="Items">建立樹的集合</param>        /// <returns>建立好的樹結(jié)構(gòu)</returns>        public List<TreeNode<T>> CreateTreeByLevel            (List<T> Items )        {            Items.Sort(new Comparison<T>(this.CompareResult));            List<TreeNode<T>> result = new List<TreeNode<T>>();            TreeNode<T> lastNode =null;            Queue<TreeNode<T>> queue = new Queue<TreeNode<T>>();            TreeNode<T> currentNode=null;            var current = result;            if (Items.Count > 0)            {                  for (int i = 0; i < Items.Count ; i++)                {                                        TreeNode<T> AddedNode = new  TreeNode<T>(){Data=Items[i],                        Parent = null,Children = new List<TreeNode<T>>()};//生成要添加的數(shù)據(jù)                     queue.Enqueue(AddedNode);//入隊(duì)                      //看是否到了下一層的結(jié)點(diǎn)                    if (lastNode != null &&                        (compare(AddedNode.Data, lastNode.Data) == Tree.TeeNodeCompareResult.Child                         || compare(AddedNode.Data, lastNode.Data) == Tree.TeeNodeCompareResult.NexLevelNode)//下一層:即結(jié)點(diǎn)是子結(jié)點(diǎn)或是下一層結(jié)點(diǎn)                        )                    {                        currentNode = queue.Dequeue();                                           }                    //找到對(duì)應(yīng)的父結(jié)點(diǎn)                    while (currentNode != null                         &&                        compare(AddedNode.Data, currentNode.Data) != TeeNodeCompareResult.Child                        )                    {                        currentNode = queue.Dequeue();                    }                    if (currentNode !=null && compare(AddedNode.Data, currentNode.Data) != TeeNodeCompareResult.EquealNode)                    {                        AddedNode.Parent = currentNode;                        current = currentNode.Children;                    }                    current.Add(AddedNode);                    lastNode = AddedNode;                }            }            return result;               }復(fù)制代碼

 

下面是一個(gè)使用的Demo ^_^

 

復(fù)制代碼//類:{    [Table(Name="Auth")]        public class Auth    {        [Column(IsKey=true)]        public string Code { get; set; }        public string Name { get; set; }        public String Url { get; set; }        public string View { get; set; }        public string Action { get; set; }        public string Text { get; set; }        public string Image { get; set; }        public override string ToString()        {            return Code + " " + Name;        }               }//比較結(jié)點(diǎn)的關(guān)系: static Soway.DB.Tree.TeeNodeCompareResult compare(Auth ob1, Auth ob2)        {            if (ob1.Code == ob2.Code)                return TeeNodeCompareResult.EquealNode;            if (ob1.Code.Length > ob2.Code.Length)                if (ob1.Code.IndexOf(ob2.Code) == 0)                    return TeeNodeCompareResult.Child;                else                    return TeeNodeCompareResult.NexLevelNode;            else if (ob1.Code.Length < ob2.Code.Length)                return TeeNodeCompareResult.Parent;            else if (ob1.Code.CompareTo(ob2.Code) < 0)                return TeeNodeCompareResult.PreNode;            else                return TeeNodeCompareResult.NextNode;                        }///主函數(shù)中 var c = new Soway.DB.DBContext(builder.ToString());            var items = c.Get<Auth  >();//初始化    var tree = new TreeFactory<Auth>(new TeeNodeCompare<Auth>(compare)).CreateTreeByLevel(items);//建立樹型結(jié)構(gòu)
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 收藏| 太仓市| 龙口市| 扎兰屯市| 开封县| 潜江市| 当雄县| 筠连县| 武冈市| 田林县| 吉隆县| 潼关县| 中阳县| 藁城市| 商城县| 怀化市| 偏关县| 宁南县| 四会市| 定边县| 涟源市| 舞钢市| 张家界市| 保靖县| 安福县| 道孚县| 山丹县| 城固县| 祁东县| 房山区| 清新县| 奉节县| 双峰县| 察哈| 寿宁县| 酒泉市| 凤台县| 海丰县| 临洮县| 正镶白旗| 青川县|