今天遇到一个求树形结构中所有节点的值求合的问题,TreeList自身提供了类似的功能,可是它的表现形式并不是我想要的,我需要将子结点的合放在父节点的值中。折腾了几下。还弄不出来,我是不喜欢接受人家东西的人。除非是自己实现不了。那是能力问题,自己想了一下。有些头绪,干脆自己来写个过程实现算了。刚开始想着用递归。说来惭愧。学编程这么久。对这个东西还是模模糊糊的印象。搞了两下。竟然不行。上网一问大虾们。被骂个半死。偶是菜鸟中的菜鸟,连二叉树的问题都搞不定。说的我当时就想去跳楼。没有办法。能力有限啊。最后想到了将树形数据转化为线型数据来处理,这样子就发挥了搜索和排序的威力。最后用Hashtable实现。到于线型数据,我用到了TreeListOperation中的Execute过程来将所有的节点加到一个Hashtable中。转换过程代码如下:
//对树形数据求和用到数据结构
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 ;
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是这样的: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
//对树形数据求和用到数据结构
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
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