Вот алгоритм, который должен делать то, что вам нужно.Предполагается, что ваши данные в порядке, поэтому он выполняет в O (n).
Во-первых, вам нужен узел, который выглядит следующим образом:
class Node {
Node Parent;
List<Node> Children = new List<Node>();
int NodeId;
string Data;
public Node(NodeRow row) { ... }
}
- Загрузить первую строку как
current
. - Загрузить следующую строку;сравните
newRow.ParentNodeId
с current.NodeId
. - Пока не найдете совпадение, установите
current = current.Parent
- Добавьте
newRow
к current.Children
и установите current
в новой строке. - Перейти к шагу 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;
}