我正在使用ASP.Net页面,其中有树视图。在树视图中,一些节点具有嵌套节点,如分支。我有以下格式的自定义对象列表中的数据:
Id,Description,parentId
现在,我正在使用一个函数以递归方式将节点添加到树视图中。以下是代码段:
private bool findParentAddNode(string id, string description, string parentid, ref List<CustomTreeNode> treeList)
{
bool isFound = false;
foreach (CustomTreeNode node in treeList)
{
if (node.id == parentid)//if current node is parent node, add in it as its child
{
node.addChild(id, description, parentid);
isFound = true;
break;
}
else if (node.listOfChildNodes != null)//have child nodes
{
isFound = findParentAddNode(id, description, parentid, ref node.listOfChildNodes);
if (isFound)
break;
}
}
return isFound;
}
上述技术运行良好,但对于超过30K节点,其性能很慢。请建议使用循环替换此递归调用的算法。
答案 0 :(得分:3)
当它向下递归树时,代码正在对子节点列表进行线性搜索。
这意味着对于随机分布的父ID,在向树添加N个节点之后,在添加第N + 1个节点之前,它将平均搜索父节点的N / 2个节点。因此,节点数量的成本为O(N²)。
而不是线性扫描,创建一个id到节点的索引,并使用它来快速查找父节点。创建节点并将其添加到树时,还要将其添加到Dictionary<int,CustomTreeNode>
。如果要将节点添加到父节点,请在索引中查找父节点并添加它。如果addChild
返回它创建的子节点,则代码变为:
Dictionary<int,CustomTreeNode> index = new Dictionary<int,CustomTreeNode>();
private bool findParentAddNode(string id, string description, string parentid)
{
if ( !nodeIndex.TryGetValue ( parentid, out parentNode ) )
return false;
index[id] = parentNode.addChild(id, description, parentid);
return true;
}
在使用findParentAddNode
之前,您需要将树的根添加到索引中。
答案 1 :(得分:-1)
广度优先搜索的迭代版本应如下所示:
var rootNodes = new List<CustomTreeNode> { new CustomTreeNode() };
while (rootNodes.Count > 0) {
var nextRoots = new List<CustomTreeNode>();
foreach (var node in rootNodes) {
// process node here
nextRoots.AddRange(node.CustomTreeNode);
}
rootNodes = nextRoots;
}
那就是说,这没有经过测试,因为它是BFS,不是最佳w / r / t内存。 (与DFS或迭代加深DFS相比,内存使用 O(n),而不是 O(log n)。
答案 2 :(得分:-1)
您可以使用 for xml 从sql server数据库返回xml格式的数据 然后将其绑定到treeview控件。