高效的TreeView构建方法

    技术2022-05-11  86

    高效的TreeView构建方法

     

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

    ID

    FatherID

    Title

    0101

    01

    基本建设支出

    010109

    0101

    其它基本建设支出

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

    因此我写下了如下代码:

    一、普通的方法

    Private Function BuildENTree(ByVal ds As DataSet)

            Dim rs As DataRowCollection

            Dim r As DataRow

            Dim ID As String

            Dim FatherID As String

            Dim Title As String

            Dim fn As TreeNode

            Dim node As TreeNode

     

            rs = ds.Tables(0).Rows

            BootNode = New TreeNode

            BootNode.Text = "[0] 所有单位"

            BootNode.Tag = "0"   '根目录

            treeEN.Nodes.Add(BootNode)

     

            For Each r In rs

                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 TreeNode

                    With node

                        .Tag = ID

                        .Text = Title

                    End With

                    fn.Nodes.Add(node)

                End If

            Next

            BootNode.Expand()

    End Function

     

    '在指定的节点下查找ID相符节点

    Private Function FindNode(ByVal n As TreeNode, ByVal ID As String) As TreeNode

            Dim ns As TreeNodeCollection

            Dim node As TreeNode

            Dim Flag As Boolean

            Dim strText As String

            Dim ReturnNode As TreeNode

     

            Flag = False

     

            If n.Tag = ID Then

                Return n

            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 ns

                    ReturnNode = FindNode(node, ID)

                    If ReturnNode Is Nothing Then

                        'do nothing

                    Else

                        Flag = True

                        Exit For

                    End If

                Next

                If Flag = True Then Return ReturnNode

            End If

            Return Nothing

        End Function

     

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

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

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

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

    那么如何来使用它呢?

     

    二、快速的方法

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

    Private FastHashTable As Hashtable

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

        Private Function BuildENTree(ByVal ds As DataSet)

            Dim rs As DataRowCollection

            Dim r As DataRow

            Dim ID As String

            Dim FatherID As String

            Dim Title As String

            Dim fn As TreeNode

            Dim node As TreeNode

     

            rs = ds.Tables(0).Rows

            BootNode = New TreeNode

            BootNode.Text = "[0] 所有单位"

            BootNode.Tag = "0"   '根目录

            treeEN.Nodes.Add(BootNode)

            FastHashTable.Add("0", BootNode)

     

            For Each r In rs

                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 TreeNode

                    With node

                        .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 TreeNode

            Return FastHashTable.Item(ID)

    End Function                               

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

    FastHashTable = New Hashtable(3000) '数量

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

    三、后记

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

     


    最新回复(0)