高效的TreeView构建方法

 

网上一直有朋友说.net上的TreeView不够快,而且也不方便。那么真实的情况是否如此呢。我做的一项目中需要一个快速的Tree,它的数据源是MS SQL,其对应表中记录的结构如下:

ID

FatherID

Title

0101

01

基本建设支出

010109

0101

其它基本建设支出

其特点是父节点的ID正好是当前记录ID的长度-2所截取的字符串

因此我写下了如下代码:

一、普通的方法

PrivateFunction BuildENTree(ByVal ds As
        Dim rs As
        Dim r As
        Dim ID As String 
   
        Dim FatherID As String 
   
        Dim Title As String 
   
        Dim fn As
        Dim node As
  
  
        rs = ds.Tables(0).Rows 
  
        BootNode = New
        BootNode.Text = "[0] 所有单位" 
  
        BootNode.Tag = "0"   '根目录 
   
        treeEN.Nodes.Add(BootNode) 
  
  
  
        For Each r In
            ID = DirectCast(r.Item(0), String).Trim   'CODE 
   
            FatherID = DirectCast(r.Item(1), String).Trim 'FATHERCODE 
   
            Title = "[" & ID & "] " & DirectCast(r.Item(2), String).Trim 'TITLE 
   
            '查找与父节点ID相同的节点 
   
            fn = FindNode(FatherID) 
   
            If fn Is Nothing Then 
   
                '没找到对应ID的节点 
   
            Else 
   
                node = New
                With
                    .Tag = ID 
  
                    .Text = Title 
  
                End With 
   
                fn.Nodes.Add(node) 
  
            End If 
   
        Next 
   
        BootNode.Expand() 
  
EndFunction 
   
  
  
'在指定的节点下查找ID相符节点 
  
PrivateFunction FindNode(ByVal n As TreeNode, ByVal ID As String) As
        Dim ns As
        Dim node As
        Dim Flag As Boolean 
   
        Dim strText As String 
   
        Dim ReturnNode As
  
  
        Flag = False 
   
  
  
        If n.Tag = ID Then 
   
            Return
        Else 
   
            '如果路径根本不相同则返回 
   
            If (ID.Length < DirectCast(n.Tag, String).Length) OrElse ((n.Tag <> "0") AndAlso (ID.Substring(0, n.Tag.Length) <> n.Tag)) Then 
   
                Return Nothing 
   
            End If 
   
  
  
            ns = n.Nodes 
  
            For Each node In
                ReturnNode = FindNode(node, ID) 
  
                If ReturnNode Is Nothing Then 
   
                    'do nothing 
   
                Else 
   
                    Flag = True 
   
                    Exit For 
   
                End If 
   
            Next 
   
            If Flag = True Then Return
        End If 
   
        Return Nothing 
   
    End Function

 

以上的代码利用将当前字节点的ID值存储于Node的Tag中,然后从根目录开始进行遍历进行查找。运行后发现其效率极为低下。但是网上的代码大多如此。

有没有其它方法可以增快其运行速度呢。

神说:“算法要么以空间换时间,要么以时间换空间”。

在某个时候我于是顿悟了。我发现我可以.net提供的HashTable,这可是个好东东。

那么如何来使用它呢?


二、快速的方法

首先我们需要增加一个定义

PrivateAs

然后需要将BuildENTree来做点小调整

Private Function BuildENTree(ByVal ds As
        Dim rs As
        Dim r As
        Dim ID As String 
   
        Dim FatherID As String 
   
        Dim Title As String 
   
        Dim fn As
        Dim node As
  
  
        rs = ds.Tables(0).Rows 
  
        BootNode = New
        BootNode.Text = "[0] 所有单位" 
  
        BootNode.Tag = "0"   '根目录 
   
        treeEN.Nodes.Add(BootNode) 
  
        FastHashTable.Add("0", BootNode) 
   
  
  
        For Each r In
            ID = DirectCast(r.Item(0), String).Trim   'CODE 
   
            FatherID = DirectCast(r.Item(1), String).Trim 'FATHERCODE 
   
            Title = "[" & ID & "] " & DirectCast(r.Item(2), String).Trim 'TITLE 
   
            '查找与父节点ID相同的节点 
   
            fn = FindNode(FatherID) 
  
            If fn Is Nothing Then 
   
                '没找到对应ID的节点 
   
            Else 
   
                node = New
                With
                    .Tag = ID 
  
                    .Text = Title 
  
                End With 
   
                fn.Nodes.Add(node) 
  
                FastHashTable.Add(ID, node) 
   
            End If 
   
        Next 
   
        BootNode.Expand() 
  
    End Function

从以上代码看出,我只是增加了两处黑体的代码,它的作用就是将新增的节点不仅存到TreeView中,还要存到FashHashTable中,其关键字是ID值,只要没有重复的ID,那么就可以使用。

接下来我们还需要对FindNode进行改变。

    '新版的快速查找

Private Function FindNode(ByVal ID As String) As
        Return
EndFunction

                       

好了,现在还有一个工作要做,就是要将FastHashTable进行初使化,尽量将其初使化成与你将要构建的数据节点数相同,我这个系统中是3000个节点,因此我增加了以下一句:

FastHashTable = New Hashtable(3000) '数量

现在,这个树已经很快了。

三、后记

即使是在.net时代,数据结构对我们也是很有用的。今天就到这儿吧!