世外桃源

C#、Asp.net相关技术

导航

TreeList使用扎记(3)

Posted on 2006-10-18 04:08  佚名  阅读(3616)  评论(1编辑  收藏  举报
今天遇到一个求树形结构中所有节点的值求合的问题,TreeList自身提供了类似的功能,可是它的表现形式并不是我想要的,我需要将子结点的合放在父节点的值中。折腾了几下。还弄不出来,我是不喜欢接受人家东西的人。除非是自己实现不了。那是能力问题,自己想了一下。有些头绪,干脆自己来写个过程实现算了。刚开始想着用递归。说来惭愧。学编程这么久。对这个东西还是模模糊糊的印象。搞了两下。竟然不行。上网一问大虾们。被骂个半死。偶是菜鸟中的菜鸟,连二叉树的问题都搞不定。说的我当时就想去跳楼。没有办法。能力有限啊。最后想到了将树形数据转化为线型数据来处理,这样子就发挥了搜索和排序的威力。最后用Hashtable实现。到于线型数据,我用到了TreeListOperation中的Execute过程来将所有的节点加到一个Hashtable中。转换过程代码如下:
 1using System;
 2using System.Collections ;
 3using DevExpress.XtraTreeList;
 4using DevExpress.XtraTreeList.Columns ;
 5using DevExpress.XtraTreeList.Nodes ;
 6using DevExpress.XtraTreeList.Nodes.Operations ;
 7namespace NskProject
 8{
 9    /// <summary>
10    ///求树形数据之和,辅助类,将数据取到Hashtable。
11    /// </summary>

12    public class GetSumItemList:TreeListOperation
13    {
14        Hashtable _ValueList=new Hashtable();
15        int _MaxLevel=0;
16        public override void Execute(TreeListNode node)
17        {
18            TreeSumData SumData=new TreeSumData();
19            SumData.Level =node.Level;
20            if(SumData.Level>_MaxLevel)
21            {
22                _MaxLevel=SumData.Level ;
23            }

24            SumData.ParentID =node.ParentNode!=null?node.ParentNode.Id+1:0;
25            SumData.ID =node.Id+1;
26            string text=node.GetDisplayText(ValueColumn);
27            double value=0;
28            if(Double.TryParse(text,System.Globalization.NumberStyles.Number,null,out value))
29            {
30                SumData.Value =value;
31            }

32            else
33            {
34                SumData.Value =0;
35            }

36            SumData.IsParent =node.HasChildren ?true:false;
37            ValueList.Add(node.Id+1 ,SumData);
38        }

39
40        TreeListColumn _ValueColumn=null;
41        public TreeListColumn ValueColumn
42        {
43            get{return _ValueColumn;}
44            set{_ValueColumn=value;}
45        }

46        public Hashtable ValueList
47        {
48            get{return _ValueList;}
49        }

50        public int MaxLevel
51        {
52            get{return _MaxLevel;}
53        }

54    }

55}

56
其中存入到Hashtable中的Struct是这样的:
//对树形数据求和用到数据结构
 public struct TreeSumData
 {
  public int Level;//深度
  public double Value;//值
  public int ParentID;//父节点ID
  public int ID;//自身ID
  public bool IsParent;//是否为父节点
 }
当得到一个线型的数据列表和该树形数据集合的最大深度后,我们就可以正式开始进行计算了。菜鸟我不会二叉树。也不会什么算法。就只好一层一层的算了。中间有大量的拆箱和装箱操作,在2005下采用List泛型实现效率应该会高一些。
  1using System;
  2using System.Collections ;
  3
  4namespace NskProject
  5{
  6    /// <summary>
  7    /// 自顶向上计算各个节点的值
  8    /// </summary>

  9    public class SumTreeDataInHashtable
 10    {
 11        Hashtable Value=new Hashtable();
 12        public SumTreeDataInHashtable(Hashtable value)
 13        {
 14            Value=value;
 15        }

 16
 17        public void SumAll()
 18        {
 19            for(int i=MaxLevel-1;i>=0;i--)
 20            {
 21                GetParentList(i);
 22            }

 23        }

 24
 25        //最大深度
 26        int _MaxLevel=0;
 27        public int MaxLevel
 28        {
 29            get{return _MaxLevel;}
 30            set{_MaxLevel=value;}
 31        }

 32        public Hashtable Result
 33        {
 34            get{return Value;}//结果输出
 35        }

 36        //单层的计算
 37        private void GetParentList(int Level)
 38        {
 39            ArrayList ID;
 40            ID=GetParentID(Level);
 41            for(int n=0;n<ID.Count;n++)
 42            {
 43                int CurrentParentID=Convert.ToInt32(ID[n]);
 44                ArrayList Current=new ArrayList();
 45                foreach(object value in Value.Values)
 46                {
 47                    TreeSumData Data=(TreeSumData)value;
 48                    if(Data.ParentID==CurrentParentID)
 49                    {
 50                        Current.Add(Data.Value);
 51                    }

 52                    else if(Data.ID==CurrentParentID)
 53                    {
 54                        Current.Add(Data.Value );
 55                    }

 56                }

 57                double SumValue=SumArrayList(Current);
 58                TreeSumData tmp=(TreeSumData)Value[CurrentParentID];
 59                tmp.Value =SumValue;
 60                Value[CurrentParentID]=tmp;
 61            }

 62        }

 63
 64
 65        /// <summary>
 66        /// 取得上层父节点有的数量
 67        /// </summary>
 68        /// <param name="Level"></param>
 69        /// <returns></returns>

 70        private ArrayList GetParentID(int Level)
 71        {
 72                            
 73            ArrayList Res=new ArrayList();
 74            foreach(object value in Value.Values)
 75            {
 76                TreeSumData Data=(TreeSumData)value;
 77                if(Data.Level ==Level)
 78                {
 79                    if(!Res.Contains(Data.ID))
 80                    {
 81                        Res.Add(Data.ID);
 82                    }

 83                }

 84            }

 85            return Res;
 86        }

 87
 88        //计算一个ArrayList中所有值的和
 89        private double SumArrayList(ArrayList Source)
 90        {
 91            double Res=0;
 92            for(int i=0;i<Source.Count;i++)
 93            {
 94                double t=Convert.ToDouble(Source[i]);
 95                Res+=t;
 96            }

 97            return Res;
 98        }

 99    }

100}

101