C# 从桌子上取下一棵树

C# 从桌子上取下一棵树,c#,database,algorithm,graph-algorithm,C#,Database,Algorithm,Graph Algorithm,我有一个包含所有节点的数据表。它们被序列化到数据库。我想创建数据的对象图(层次)表示。似乎有几种方法可以做到这一点 (这意味着在树完全构建之前需要对数据表进行大量搜索) 是否有Order-N方法?在我的例子中,我已将数据表中树的节点预先排序为In Order形式。也就是说,第一行为父级显示空值,因为它是根。随后的每一行都按顺序排列 我似乎回忆起我上学时的一种N阶方法。但我不记得了 我的DataTable架构类似于以下内容: NodeID-int ParentNodeId-可为空 数据字符串 这

我有一个包含所有节点的数据表。它们被序列化到数据库。我想创建数据的对象图(层次)表示。似乎有几种方法可以做到这一点

(这意味着在树完全构建之前需要对数据表进行大量搜索)

是否有Order-N方法?在我的例子中,我已将数据表中树的节点预先排序为In Order形式。也就是说,第一行为父级显示空值,因为它是根。随后的每一行都按顺序排列

我似乎回忆起我上学时的一种N阶方法。但我不记得了

我的DataTable架构类似于以下内容:

  • NodeID-int
  • ParentNodeId-可为空
  • 数据字符串

这里有一个算法,它可以完成您需要它做的事情。它假定您的数据是有序的,因此它以O(n)的形式执行

首先,您需要一个如下所示的节点:

class Node {
    Node Parent;
    List<Node> Children = new List<Node>();
    int NodeId;
    string Data;
    public Node(NodeRow row) { ... }
}

可能相关:使用字典跟踪父节点,这可能是最简单的方法。我使用了一个不需要字典的递归解决方案,但是太长时间了,我不得不再次推导它。这看起来不像是顺序形式。如果是这样,root就不会是表中的第一个节点。你是说预购吗?谢谢!有点小问题。在Node类中,您已经将父节点列为完整格式的节点。我所拥有的只是父节点的ID。为了完全形成父节点,我必须为每个节点执行DataTable搜索。所以我们又回到了那个话题——额外的查找。从我的数据库中得到的是一列,它告诉我父项的ID。行是按顺序排列的。对不起,我忘记了一行:
rowNode.Parent=current。对于每一新行,我们遍历树,查找匹配的
ParentNodeId
。然后,新的
rowNode.Parent
被设置为
current
。。。。由于数据是“有序的”,我们知道
ParentNodeId
必须与
当前的
祖先之一匹配。这就是给我们的
O(n)
Node CreateTree(IEnumerable<NodeRow> rows) {
    Node root = null;
    Node current = null;
    foreach (var row in rows) {
        // Root:
        if (root == null) { 
            root = current = new Node(row);
            continue;
        }
        // Traverse up the tree until the parent is found:
        while (row.ParentNodeId != current.NodeId) {
            current = current.Parent;
        }
        // Add the new node as a child of the current one:
        var rowNode = new Node(row);
        rowNode.Parent = current;
        current.Children.Add(rowNode);
        current = rowNode;
    }
    return root;
}