不用递归的TreeView构建方法(优化方案)

高效的TreeView构建方法<o:p></o:p>

 <o:p></o:p>

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

ID

FatherID

Title

0101

01

基本建设支出

010109

0101

其它基本建设支出

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

因此我写下了如下代码:<o:p></o:p>

一、普通的方法<o:p></o:p>

Private Function BuildENTree(ByVal ds As DataSet)<o:p></o:p>

        Dim rs As DataRowCollection<o:p></o:p>

        Dim r As DataRow<o:p></o:p>

        Dim ID As String<o:p></o:p>

        Dim FatherID As String<o:p></o:p>

        Dim Title As String<o:p></o:p>

        Dim fn As TreeNode<o:p></o:p>

        Dim node As TreeNode<o:p></o:p>

 <o:p></o:p>

        rs = ds.Tables(0).Rows<o:p></o:p>

        BootNode = New TreeNode<o:p></o:p>

        BootNode.Text = "[0] 所有单位"<o:p></o:p>

        BootNode.Tag = "0"   '根目录<o:p></o:p>

        treeEN.Nodes.Add(BootNode)<o:p></o:p>

 <o:p></o:p>

        For Each r In rs<o:p></o:p>

            ID = DirectCast(r.Item(0), String).Trim   'CODE<o:p></o:p>

            FatherID = DirectCast(r.Item(1), String).Trim 'FATHERCODE<o:p></o:p>

            Title = "[" & ID & "] " & DirectCast(r.Item(2), String).Trim 'TITLE<o:p></o:p>

            '查找与父节点ID相同的节点<o:p></o:p>

            fn = FindNode(FatherID)<o:p></o:p>

            If fn Is Nothing Then<o:p></o:p>

                '没找到对应ID的节点<o:p></o:p>

            Else<o:p></o:p>

                node = New TreeNode<o:p></o:p>

                With node<o:p></o:p>

                    .Tag = ID<o:p></o:p>

                    .Text = Title<o:p></o:p>

                End With<o:p></o:p>

                fn.Nodes.Add(node)<o:p></o:p>

            End If<o:p></o:p>

        Next<o:p></o:p>

        BootNode.Expand()<o:p></o:p>

End Function<o:p></o:p>

 <o:p></o:p>

'在指定的节点下查找ID相符节点<o:p></o:p>

Private Function FindNode(ByVal n As TreeNode, ByVal ID As String) As TreeNode<o:p></o:p>

        Dim ns As TreeNodeCollection<o:p></o:p>

        Dim node As TreeNode<o:p></o:p>

        Dim Flag As Boolean<o:p></o:p>

        Dim strText As String<o:p></o:p>

        Dim ReturnNode As TreeNode<o:p></o:p>

 <o:p></o:p>

        Flag = False<o:p></o:p>

 <o:p></o:p>

        If n.Tag = ID Then<o:p></o:p>

            Return n<o:p></o:p>

        Else<o:p></o:p>

            '如果路径根本不相同则返回<o:p></o:p>

            If (ID.Length < DirectCast(n.Tag, String).Length) OrElse ((n.Tag <> "0") AndAlso (ID.Substring(0, n.Tag.Length) <> n.Tag)) Then<o:p></o:p>

                Return Nothing<o:p></o:p>

            End If<o:p></o:p>

 <o:p></o:p>

            ns = n.Nodes<o:p></o:p>

            For Each node In ns<o:p></o:p>

                ReturnNode = FindNode(node, ID)<o:p></o:p>

                If ReturnNode Is Nothing Then<o:p></o:p>

                    'do nothing<o:p></o:p>

                Else<o:p></o:p>

                    Flag = True<o:p></o:p>

                    Exit For<o:p></o:p>

                End If<o:p></o:p>

            Next<o:p></o:p>

            If Flag = True Then Return ReturnNode<o:p></o:p>

        End If<o:p></o:p>

        Return Nothing<o:p></o:p>

    End Function<o:p></o:p>

 <o:p></o:p>

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

有没有其它方法可以增快其运行速度呢。<o:p></o:p>

神说:“算法要么以空间换时间,要么以时间换空间”。<o:p></o:p>

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

那么如何来使用它呢?<o:p></o:p>

 <o:p></o:p>

二、快速的方法<o:p></o:p>

首先我们需要增加一个定义<o:p></o:p>

Private FastHashTable As Hashtable<o:p></o:p>

然后需要将BuildENTree来做点小调整<o:p></o:p>

    Private Function BuildENTree(ByVal ds As DataSet)<o:p></o:p>

        Dim rs As DataRowCollection<o:p></o:p>

        Dim r As DataRow<o:p></o:p>

        Dim ID As String<o:p></o:p>

        Dim FatherID As String<o:p></o:p>

        Dim Title As String<o:p></o:p>

        Dim fn As TreeNode<o:p></o:p>

        Dim node As TreeNode<o:p></o:p>

 <o:p></o:p>

        rs = ds.Tables(0).Rows<o:p></o:p>

        BootNode = New TreeNode<o:p></o:p>

        BootNode.Text = "[0] 所有单位"<o:p></o:p>

        BootNode.Tag = "0"   '根目录<o:p></o:p>

        treeEN.Nodes.Add(BootNode)<o:p></o:p>

        FastHashTable.Add("0", BootNode)<o:p></o:p>

 <o:p></o:p>

        For Each r In rs<o:p></o:p>

            ID = DirectCast(r.Item(0), String).Trim   'CODE<o:p></o:p>

            FatherID = DirectCast(r.Item(1), String).Trim 'FATHERCODE<o:p></o:p>

            Title = "[" & ID & "] " & DirectCast(r.Item(2), String).Trim 'TITLE<o:p></o:p>

            '查找与父节点ID相同的节点<o:p></o:p>

            fn = FindNode(FatherID)<o:p></o:p>

            If fn Is Nothing Then<o:p></o:p>

                '没找到对应ID的节点<o:p></o:p>

            Else<o:p></o:p>

                node = New TreeNode<o:p></o:p>

                With node<o:p></o:p>

                    .Tag = ID<o:p></o:p>

                    .Text = Title<o:p></o:p>

                End With<o:p></o:p>

                fn.Nodes.Add(node)<o:p></o:p>

                FastHashTable.Add(ID, node)<o:p></o:p>

            End If<o:p></o:p>

        Next<o:p></o:p>

        BootNode.Expand()<o:p></o:p>

    End Function<o:p></o:p>

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

接下来我们还需要对FindNode进行改变。<o:p></o:p>

    '新版的快速查找<o:p></o:p>

    Private Function FindNode(ByVal ID As String) As TreeNode<o:p></o:p>

        Return FastHashTable.Item(ID)<o:p></o:p>

End Function                                <o:p></o:p>

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

FastHashTable = New Hashtable(3000) '数量<o:p></o:p>

现在,这个树已经很快了。<o:p></o:p>

三、后记<o:p></o:p>

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值