老有人问树型算法,今天有个网友问我,我就把它拿出来分享给大家,免得遇到的朋友又搞半天(2006-02-22 15:36:17)   平沙落雁
你好,能问你一个问题吗,很急的
 
(2006-02-22 15:37:30)   平沙落雁
就在在C#winform中如何建立一棵下面内容的树目录,
用的是treeView控件(2006-02-22 15:40:17)   平沙
内容是:
ClassID   ClassName
1         aa
11        bb
1101      cc
110101    dd
110102    ee
12        ff
1201      gg
120101    hh
120102    ii
13        jj
1301      kk
130101    ll
130102    mm
14        nn
1401      oo
15        pp
1501      qq (2006-02-22 15:41:41)   长江支流
数据结构设计成ClassID   ClassName ParentID
  
(2006-02-22 15:42:37)   长江支流
ClassID   ClassName结构有些弱点,查询速度慢,你只能是Like(2006-02-22 15:43:16)   平沙落雁
不行,因为这个数据以开发好了,我只想在外面做点其它功能,数据库不能改的(2006-02-22 15:44:02)   长江支流
而且还要有潜规则,如你这个编辑规则1--1-2-,如120101就是1 2 01 01,我用空格分出了你的级次 ...这个网友说弄了好长时间没弄出来,说比较急,那就帮解决了,顺便就贴出来:
/// <summary>
/// 将指定的级别加载到指定的树目录节点(若有下一级目录,递归调用)。
/// </summary>
/// <param name="treenode">要加载的信息树型目录,类型为System.Windows.Forms.TreeNode,此目录作为此级别的父目录</param>
/// <param name="Level">要加载的级别,如果你的数据结构是ClassID、ClassName而没有Level,就需要你事先根据层次关系编码规则确定,如1201001,如果是1-1-2-3的编辑规则,实际层次关系是1 2 01 001。</param>
/// <param name="StartCode">此级别开始字符串(过渡同级别但不同类的数据)</param>
/// <res>
/// 作 者:周方勇[长江支流]
/// 修改日期:2002-10-21
/// </res>
public void FetchTreeNode(System.Windows.Forms.TreeNode p_TreeNode,int p_Level,string p_StartCode)
{
//类型级别数组ClassLevel Array
ClassLevel[] cla; //对象管理
ClassLevelManager clm = new ClassLevelManager(); //获取此级别的元素
cla = clm.Fetch(p_Level,p_StartCode); //以上实现是对象管理方式实现,返回的是对象集合,每个对象应用ORMap,你可以根据数据库直接返回DataTable在下面循环处读取。 //加载
for (int i = 0 ; i < cla.Length ; i++ )
{
System.Windows.Forms.TreeNode tn = new System.Windows.Forms.TreeNode(cla[i].Code + cla[i].Name); tn.Tag = cla[i].Code;
p_TreeNode.Nodes.Add(tn);

//如果不是未级,递归调用
//if (cla[i].IsLastLevel == false)
FetchTreeNode(tn,p_Level + 1,cla[i].Code);
}
}
/// <summary>
/// 将指定的级别加载到指定的树目录节点(若有下一级目录,递归调用)
/// </summary>
/// <param name="treenode">要加载的信息树型目录,类型为Microsoft.Web.UI.WebControls.TreeNode,此目录作为此级别的父目录</param>
/// <param name="Level">要加载的级别,如果你的数据结构是ClassID、ClassName而没有Level,就需要你事先根据层次关系编码规则确定,如1201001,如果是1-1-2-3的编辑规则,实际层次关系是1 2 01 001。</param>
/// <param name="StartCode">此级别开始字符串(过渡同级别但不同类的数据)</param>
/// <res>
/// 作 者:周方勇[长江支流]
/// 修改日期:2002-10-21
/// </res>
public void FetchTreeNode(Microsoft.Web.UI.WebControls.TreeNode p_TreeNode,int p_Level,string p_StartCode)
{
//类型级别数组ClassLevel Array
ClassLevel[] cla; //对象管理
ClassLevelManager clm = new ClassLevelManager(); //获取此级别的元素
cla = clm.Fetch(p_Level,p_StartCode); //以上实现是对象管理方式实现,返回的是对象集合,每个对象应用ORMap,你可以根据数据库直接返回DataTable在下面循环处读取。 //加载
for (int i = 0 ; i < cla.Length ; i++ )
{
Microsoft.Web.UI.WebControls.TreeNode tn = new Microsoft.Web.UI.WebControls.TreeNode();
tn.ID = cla[i].Code;
tn.Text = cla[i].Name; //tn. = cla[i].Code;
p_TreeNode.Nodes.Add(tn);

//如果不是未级,递归调用(是不是都无所谓了,因为不指定未级,进行下一次递归,发现它没有下级了会退出本次递归。不指定是否未级,也可以,只是性能上差了一点。)
//if (cla[i].IsLastLevel == true)
FetchTreeNode(tn,p_Level + 1,cla[i].Code);
}
}

解决方案 »

  1.   

    以上实现就是基于传统的树型,朋友们如果是新建数据结构,请使用
    ClassID   ClassName ParentID这种方式速度比较快,直接根据DataView的Filter就可以把子级查出来,应用递归就可以了。这是一种思路,建议想做而不急的朋友自己实现,实现后看看效率。如果数据量不超过3000,大家可以一试,加载一颗树要1分钟。改进算法就是应用DataTable.SelectRow方法,速度奇快,2秒钟搞定。
      

  2.   

    估计还有人对ORMap不明白,大家用DataTable、DataRow取代它就可以了。(2006-02-22 16:27:15)   离家出走
    ClassLevelManager这个是什么类型 
    (2006-02-22 16:27:10)   长江支流
    就是取数据   
    (2006-02-22 16:27:36)   长江支流
    你要看注释啊,你自己直接用DataTable把数据返回来你读DataRow就OK了 
    (2006-02-22 16:30:36)   离家出走
    ClassLevel[] 这个数组我要在外面定义吧,是string类型的吧 
    (2006-02-22 16:34:08)   长江支流
    这就是一个对象,和数据库的表是对应的,就是所谓的ORMap,所以你可以不用这种方式,直接用DataTable就可以了 
      

  3.   

    ClassLevel[] cla;//对象管理
    ClassLevelManager clm = new ClassLevelManager();//获取此级别的元素
    cla = clm.Fetch(p_Level,p_StartCode);上面那段东东,谁能不改成DataTable的功能呀,有急用
      

  4.   

    晕,这些也叫算法,用一个HashTable就可以快速加载、查找树节点,具体的代码我懒得再用C#写一遍了,
    我有一个VB.net的,大家将就看吧,清晰明了
    源码见我的Bloghttp://Blog.csdn.net/BlueDog