即使对于经验丰富的程序员来说,递归构建树也是一项艰巨的挑战。考虑到它最初是在 2011 年 3 月发布的,我意识到我在这个问题上有点迟到了。迟到总比没有好?
创建树的一个重要因素就是确保您的数据集格式正确。您只需要一种将父母与孩子联系起来的方法。明确定义关联后,您就可以开始编写解决方案了。我选择使用这样的简单格式:
ParentId ChildId
1 2
1 3
2 4
3 5
等等
一旦建立了这种关系,我就开发了一种递归方法来遍历数据集以构建树。
首先,我识别所有父节点并将它们存储在一个集合中,使用父 ID 和子 ID 的组合为每个节点提供一个唯一标识符:
private void IdentifyParentNodes()
{
SortedList<string, MyTreeNode> newParentNodes = new SortedList<string,MyTreeNode>();
Dictionary<string, string> parents = new Dictionary<string, string>();
foreach (MyTreeNode oParent in MyTreeDataSource.Values)
{
if (!parents.ContainsValue(oParent.ParentId))
{
parents.Add(oParent.ParentId + "." + oParent.ChildId, oParent.ParentId);
newParentNodes.Add(oParent.ParentId + "." + oParent.ChildId, oParent);
}
}
this._parentNodes = newParentNodes;
}
然后根调用方法会循环遍历父母并调用递归方法来构建树:
// Build the rest of the tree
foreach (MyTreeNode node in ParentNodes.Values)
{
RecursivelyBuildTree(node);
}
递归方法:
private void RecursivelyBuildTree(MyTreeNode node)
{
int nodePosition = 0;
_renderedTree.Append(FormatNode(MyTreeNodeType.Parent, node, 0));
_renderedTree.Append(NodeContainer("open", node.ParentId));
foreach (MyTreeNode child in GetChildren(node.ParentId).Values)
{
nodePosition++;
if (IsParent(child.ChildId))
{
RecursivelyBuildTree(child);
}
else
{
_renderedTree.Append(FormatNode(MyTreeNodeType.Leaf, child, nodePosition));
}
}
_renderedTree.Append(NodeContainer("close", node.ParentId));
}
用于获取父级子级的方法:
private SortedList<string, MyTreeNode> GetChildren(string parentId)
{
SortedList<string, MyTreeNode> childNodes = new SortedList<string, MyTreeNode>();
foreach (MyTreeNode node in this.MyTreeDataSource.Values)
{
if (node.ParentId == parentId)
{
childNodes.Add(node.ParentId + node.ChildId, node);
}
}
return childNodes;
}
没有那么复杂或优雅,但它完成了工作。这是在 2007 年的时间范围内编写的,所以它是旧代码,但它仍然有效。 :-) 希望这会有所帮助。