假设我有一个表示嵌套集合层次结构的列表(示例在伪c#中)。如何将嵌套集有效转换为对象层次结构
class Node
{
public decimal left;
public decimal right;
public decimal id;
public void AddChild(Node child) {...}
...
}
List<Node> nodes = GetFlatNodesWithoutChildrenSetFromDatabase();
字段left
,right
和id
得到填补,因为这些值存储在数据库中的一些。
什么是将这个扁平列表转换为层次的有效方式,这意味着为每个父节点填充适当的子节点?
一种方法是找到每个节点的所有祖先,对它们进行排序以找到父节点并将子节点添加到该节点。
foreach (var n in nodes)
{
var parent = nodes.Where(i => i.left < n.left && i.right > n.right).OrderBy(i => i.right - n.right).FirstOrDefault();
if (parent != null)
parent.AddChild(n);
}
但是这样效率很低。
有没有更好的(这意味着更快)的方法?
编辑
可能的解决方法(as suggested by Chris):
var stack = new Stack<Node>(nodes.Take(1));
foreach (var n in nodes.Skip(1))
{
while (stack.Peek().right < n.left)
stack.Pop();
stack.Peek().addChild(n);
stack.Push(n);
}
节点必须由left
订购。
“左”和“右”在某种程度上代表孩子吗? –
是的,我发现很难弄清楚你正在做什么左右两边获得父节点... – Chris
左和右是描述节点在嵌套集合中的位置的数字http:// en.wikipedia.org/wiki/Nested_set_model – sloth