【问题标题】:Hydrate a tree from a table从桌子上给一棵树补水
【发布时间】:2011-10-23 03:39:30
【问题描述】:

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

This article describes a high order method(意味着在完全构建树之前需要对 DataTable 进行大量搜索)

是否有 Order-N 方法? 就我而言,我已将 DataTable 中树的节点预排序为有序形式。意思是,第一行显示父级的NULL,因为它是根。随后的每一行都按in-order notation 排序。

我似乎想起了我学生时代的 Order-N 方法。但我不记得了。

我的 DataTable 架构类似于:

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

【问题讨论】:

  • 可能相关:stackoverflow.com/questions/444296/… 这使用字典来跟踪父节点,这可能是最简单的方法。我使用了一个不需要字典的递归解决方案,但已经很久了,我不得不再次推导它。
  • 这看起来不像是有序的形式。如果是这种情况,root 就不会是表中的第一个节点。您是说预购吗?

标签: c# database algorithm graph-algorithm


【解决方案1】:

这里有一个算法应该可以做你需要做的事情。它假设您的数据是有序的,因此它在 O(n) 中执行。

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

class Node {
    Node Parent;
    List<Node> Children = new List<Node>();
    int NodeId;
    string Data;
    public Node(NodeRow row) { ... }
}
  1. 将第一行加载为current
  2. 加载下一行;比较 newRow.ParentNodeIdcurrent.NodeId
  3. 直到找到匹配项,设置current = current.Parent
  4. newRow 添加到current.Children 并将current 设置为新行。
  5. 转到第 2 步。

就是这样!如果保证您的数据结构正确,那么您将无需进行任何额外的null 检查。

示例:

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;
}

【讨论】:

  • 谢谢!出了点小问题。在 Node 类中,您将 Parent 列为完整的 Node。我只有父母的身份证。为了完全形成父节点,我必须为每个节点执行数据表搜索。所以我们又回到了那个——额外的查找。来自我的数据库的内容是一个告诉我父母 ID 的列。这些行是有序的。
  • 对不起,我忘记了一行:rowNode.Parent = current;。对于每一行,我们遍历树,寻找匹配的ParentNodeId。然后,将新的rowNode.Parent 设置为current
  • ... 由于数据是“有序”的,我们知道ParentNodeId 必须匹配current 的祖先之一。这就是给我们O(n)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多