C#从邻接树排序数据 [英] c# sorting data from an adjacency tree

查看:100
本文介绍了C#从邻接树排序数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堆数据将被表示为一棵树.我正在使用的控件要求数据正确排序.

I have a bunch of data that will be represented as a tree. The control that I'm using requires the data to be ordered correctly.

这是每个节点的结构:

public class TreeNode
{
    public Guid id { get; set; }
    public string name { get; set; }
    public int level { get; set; }
    public Guid? parent { get; set; }
    public bool isLeaf { get; set; }    
}

我需要一种对数据进行排序的方法,这样我便有了一个TreeNodes列表,该列表首先是根,然后是其子节点,依此类推.换句话说,所有直系子女都必须跟随列表中的父母.

I need a way to sort the data so that I have a list of TreeNodes with the root first, followed by its children and so on. In other words all direct children need to follow the parent in the list.

我还希望按名称对子节点和叶节点进行排序. (> =可扩展,o =叶子)

I would also like subnodes and leaf nodes to be sorted by name. (> = expandable, o = leaf)

root >
  level1a >         
  level1b >
     level2d >
     level2a o
  level1a o
  level1b o

有一种简单的方法吗?

我假设我将需要一些递归函数,并且无法使用order by语句的组合(例如list.OrderBy(x => x.parent).ThenBy(x => x.level).ThenBy(x => x.isLeaf);之类)对它进行排序

I'm assuming I'll need some recursive function and not wont be able to sort it using a combination of order by statements (something like list.OrderBy(x => x.parent).ThenBy(x => x.level).ThenBy(x => x.isLeaf);)

推荐答案

使用正确的LINQ表达式这样做并非易事,这是正确的.这种递归方法应该可以解决问题:

You're correct that doing this with a single LINQ expression is not straightforward. This recursive approach should do the trick:

IEnumerable<TreeNode> TreeOrder(
    IEnumerable<TreeNode> nodes)
{
    //Find the root node
    var root = nodes.Single(node => node.parent == null);

    //Build an inverse lookup from parent id to children ids
    var childrenLookup = nodes
        .Where(node => node.parent != null)
        .ToLookup(node => node.parent.Value);

    return TreeOrder(root, childrenLookup);
}

IEnumerable<TreeNode> TreeOrder(
    TreeNode root,
    ILookup<Guid, TreeNode> childrenLookup)
{
    yield return root;

    if (!childrenLookup.Contains(root.id))
        yield break;

    foreach (var child in childrenLookup[root.id])
        foreach (var node in TreeOrder(child, childrenLookup))
            yield return node;
}

这篇关于C#从邻接树排序数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆