c# - 将深度数组转换为树的高效算法

标签 c# algorithm tree

我有一个存储过程,它返回按树组织的名称的平面列表。为了传达谁是有深度值的父级,所以 5 条记录(上升到 3 级)的结果如下所示:

Depth|Name
----------
    0|Ford
    1|Compact Cars
    2|Pinto
    1|Trucks
    2|H-Series

我试图通过读取深度值从这个数组中构建一个树。是否有一些明显的算法可以从这样的数据序列中构建树?我添加 C# 标签是因为我对 LINQy 解决这个问题持开放态度,尽管通用的计算机科学答案会非常有帮助。

这是我目前的尝试:

class Record
{
  public string Name{ get; set; }
  public List<Record> children { get; set; }
}

var previousLevel = 0;
var records = new List<Record>();

foreach (var thing in TreeFactory.fetch(dao))
{
  if(this.Depth == 0) {
    //Root node
  } else if(thing.Depth > previousLevel) {
    //A Child of the last added node
  } else if(thing.Depth < previousLevel) {
    //A Cousin of the last added node
  } else {
    //A Sibling of the of the last added node
  }
  previousLevel = this.Depth;
}

我所说的“高效”是指列表大小高达 200,000 个元素和树扩展到 100 个级别,所以实际上我只是在寻找更容易推理的东西。

最佳答案

这里不需要递归。我相信最快的方法是这样的:

public static TreeView TreeFromArray(Item[] arr)
{
    var tv = new TreeView();
    var parents = new TreeNodeCollection[arr.Length];
    parents[0] = tv.Nodes;

    foreach (var item in arr)
    {
        parents[item.Depth + 1] = parents[item.Depth].Add(item.Name).Nodes;
    }

    return tv;
}

项目是任何具有深度和名称信息的东西:

public class Item
{
    public int Depth;
    public string Name;
}

当使用我自己的 TreeNode 实现时,为了简化过程并将它从拖慢整个过程的不需要的功能中去除,并稍微改变方法以适应这些变化,我想出了这个:

类:

    public class Node
    {
        public string Name;
        public List<Node> Childs = new List<Node>();
    }

    public class Item
    {
        public int Depth;
        public string Name;
    }

实现:

    public static Node TreeFromArray(Item[] arr)
    {
        var tree = new Node();

        var parents = new Node[arr.Length];
        parents[0] = tree;

        foreach (var item in arr)
        {
            var curr = parents[item.Depth + 1] = new Node {Name = item.Name};
            parents[item.Depth].Childs.Add(curr);
        }

        return tree;
    }

结果:

With the given data: 1,000,000 times in 900 milliseconds

关于c# - 将深度数组转换为树的高效算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12146214/

相关文章:

c# - FindBy 注释用于查找 WebElements 列表

algorithm - 在 Scala 中编写 `indexBy` 的最佳方法是什么?

javascript - 当我左键单击 Dojo 中的树行(树节点)时,如何从 Objectstore 获取 ID?

r - 如何使用文本绘制水平而不是因子变量 rpart 的标签/索引?

jquery - 如何在 django 中创建嵌套多选树

c# - 帮助将 VB.NET "Handles"语句转换为 C#

c# - 尽管使用 Console.Read(),控制台窗口仍关闭

c# - 使用 Dot Net 的标准身份验证收集额外信息

c# - SOA - 测试算法 10^62 键

algorithm - 什么时候在树中使用父指针?