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

转载 2006年06月23日 10:39:00

高效的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时代,数据结构对我们也是很有用的。今天就到这儿吧!

 

treeview递归方法 查询节点

  • 2011年04月04日 15:02
  • 50KB
  • 下载

Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)

Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间) 本文主要解决一个问题,如何实现二叉树的前中后序遍历,有两个要求: 1. O(1)空间复杂...

C# TreeView递归添加子节点

  • 2015年07月17日 16:01
  • 52KB
  • 下载

Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)

转自http://www.cnblogs.com/AnnieKim/archive/2013/06/15/MorrisTraversal.html 文主要解决一个问题,如何实现二叉树...

C# TreeView无限递归绑定 CheckBox

  • 2013年01月30日 09:45
  • 6KB
  • 下载

ASP.NET-Treeview-递归生成部门树

  • 2013年07月05日 21:21
  • 26KB
  • 下载

Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间,修改二叉树)

本文主要解决一个问题,如何实现二叉树的前中后序遍历,有两个要求: 1. O(1)空间复杂度,即只能使用常数空间; 2. 二叉树的形状不能被破坏(中间过程允许改变其形状)。 通常,实现二叉树的前序...
  • taoqick
  • taoqick
  • 2014年03月14日 12:59
  • 752

WinForm_TreeView递归绑定Demo

  • 2011年03月25日 14:12
  • 49KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:不用递归的TreeView构建方法(优化方案)
举报原因:
原因补充:

(最多只允许输入30个字)