【问题标题】:Getting the last child in a self-referencing hierachical tree获取自引用分层树中的最后一个孩子
【发布时间】:2015-06-23 03:47:10
【问题描述】:

我有以下类型:

public class Category
{
    public string Id { get; set; }
    public string ParentId { get; set; }
    public string Title { get; set; }
}

顶级类别的 ParentId 值为 0。任何子类别都通过 ParentId 属性与其各自的父类别相关。

我正在尝试实现一种很好的方法来确定树中的最后一个孩子(无论树有多深),因此在下面的示例中,我希望返回“笔记本电脑”条目(或其至少 ID):

Id:10 ParentId:0 Title:出售

Id:5 ParentId:10 Title:计算机

Id:20 ParentId:5 Title:笔记本电脑

即层次结构是“待售”>“计算机”>“笔记本电脑”。

此层次结构可能仅包含 1 个类别,或者在某些情况下可能有 5 个以上的子级。

【问题讨论】:

  • 您的速度/内存限制是多少?您可以使用 DFS 或递归
  • 你能更准确地定义 last 吗?这是任何分支中的最后一个孩子(因为每个分支可以有多个孩子),还是最深的孩子?
  • 等等...你有一个列表中的所有项目还是只有根类别?
  • 我正在处理相同的结构,但是(啊!)在 PHP/Javascript/MySql 中。我添加了几个有用的参数:“可视化顺序”和“分支 ID”。然后我制作了类似 IP 的点代码(它们是唯一的),简单地将所有“分支 ID”链接起来。在您的情况下,“1.5.20.3.12”可能是“待售 - 计算机 - 笔记本电脑 - IBM - Thinkpad”,但更容易知道您有多少 1.5.20 或 1.5.20.3。
  • 'in a self-reference hierachical tree' 即你的意思是一个图(即a 可以是b 的父级,c 的父级是a 的父级)?如果是这样,“最后”是什么意思?

标签: c# relationship hierarchy hierarchical-data


【解决方案1】:

使用 LINQ,您可以像这样简单地实现:

var LeafNodes = YourItemsList.Where(x => !YourItemsList.Any(y => y.ParentID == x.Id));

现在您可以遍历这个可枚举对象,并且对于每个项目,您可以向上遍历父节点以获得完整的链。

【讨论】:

  • 这是对列表中的每个项目进行线性搜索,这与集合的大小非常很差。
  • @Servy:嗯... OP 说他每个类别最多可以有 5 个以上的项目,所以我猜他不会错过超过几微秒的时间。但是,对于较大的列表,您的观点非常有效。
  • 每个类别最多有 5 个孩子。但是如果有 1,000 个类别需要执行此操作...
【解决方案2】:

通过以父 ID 作为键创建查找,您可以轻松找到给定节点的所有子节点,从而轻松找到没有任何子节点的所有节点。

var lookup = categories.ToLookup(category => category.ParentId);
var leaves = categories.Where(category => !lookup[category.Id].Any());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 1970-01-01
    相关资源
    最近更新 更多