【问题标题】:Getting the father-children relationships获取父子关系
【发布时间】:2012-08-09 18:09:35
【问题描述】:

假设我们有一个具有 TreeView 的 Windows 应用程序,您可以展开该视图的节点并向下钻取到子节点,它们可能还有更多子节点,所以现在我们可以展开该节点并走得更远,等等。 . 所以在我的源代码中我有一个方法Foo(string fatherNode) 获取我们点击的父节点并找到子节点并列出它们:

这个方法的高层是这样的:

private void Foo(string fatherNode)
{
  // call some DB scripts and grab data you need to work with.
  int numberOfKids = // get it from the thing you populated from the DB call.
  for(int i = 1  to numberOfKids)
  {
     Node Child = // grab child[i] from the list we populated from DB calls
     //Add it to the treeView
  }
}

这个代码对于 UI 应用程序来说是很好的,我们点击一​​个节点,它运行这个方法一次并收集它需要的数据,现在我需要编写另一个方法,利用上面的方法的有用行一次抓取所有东西并将整个信息写入一个文件。

所以在我看来,in 对我来说是一种递归方法。但仍然无法弄清楚全貌,Prob 应该有两个集合,一个给父亲,一个给孩子,循环遍历孩子并进行递归调用以获取更多孩子并将它们添加到集合中,等等

我想知道您是否可以清除迷雾,我需要做的高级操作,集合应该是什么样子,在哪里添加它们,在哪里调用递归方法调用等等。 .不要专门考虑“treeview”对象,我只是用它作为一个例子来更好地解释这个问题。最主要的是我发布的 Foo 方法的结构。这就是我应该使用的。

【问题讨论】:

  • (1) 您能否提供该列表的类,这样我们就不会只考虑 TreeView 了吗? (2) 抓住一切是什么意思?
  • @AndreCalil :通过抓住一切:我的意思是所有父亲和所有孩子的父亲和他们的孩子的整个等级制度。不只是我们可以点击树视图的特定的...可以把它想象成导出树视图可以显示的整个数据层次结构,如果它的所有节点一次展开。
  • 第 1 条评论 //call some db script 是否仅获取父节点和子节点信息的数据,而不是更深入?
  • 好的。您希望它如何呈现?
  • @Ankush :是的,它只是加载当前的,不会更深入。

标签: c# collections recursion


【解决方案1】:

好吧,我不确定这是否是您正在寻找的东西,即使在其他答案之后也是如此。 但是,请检查一下:

自相关实体(节点)

public class MyEntity
{
    public MyEntity() { }

    public MyEntity(string Name, int ID, int? ParentID)
    {
        this.Name = Name;
        this.ID = ID;
        this.ParentID = ParentID;
    }

    public string Name { get; set; }
    public int ID { get; set; }
    public int? ParentID { get; set; }
}

建树方法

    public static StringBuilder GetFamilyTree(List<MyEntity> AllTheEntities)
    {
        StringBuilder Return = new StringBuilder();

        List<MyEntity> OrderedEntities = AllTheEntities.OrderBy<MyEntity, int>(x => x.ID).ToList();

        foreach (MyEntity CurrentEntity in AllTheEntities.Where<MyEntity>(x => !x.ParentID.HasValue))
        {
            Return.AppendLine(GetEntityTree(AllTheEntities, CurrentEntity));
        }

        return Return;
    }

    public static string GetEntityTree(List<MyEntity> AllTheEntities, MyEntity CurrentEntity, int CurrentLevel = 0)
    {
        StringBuilder Return = new StringBuilder();

        Return.AppendFormat("{0}{1}", "\t".Repeat(CurrentLevel), CurrentEntity.Name);
        Return.AppendLine();

        List<MyEntity> Children = AllTheEntities.Where<MyEntity>(x => x.ParentID.HasValue && x.ParentID.Value == CurrentEntity.ID).ToList();

        if (Children != null && Children.Count > 0)
        {
            foreach (MyEntity CurrentChildEntity in Children)
            {
                Return.Append(GetEntityTree(AllTheEntities, CurrentChildEntity, CurrentLevel + 1));
            }
        }

        return Return.ToString();
    }

一个小助手类

public static class StringExtension
{
    public static string Repeat(this string text, int times)
    {
        string Return = string.Empty;

        if (times > 0)
        {
            for (int i = 0; i < times; i++)
            {
                Return = string.Concat(Return, text);
            }
        }

        return Return;
    }
}

用法

        List<MyEntity> AllMyEntities = new List<MyEntity>();
        AllMyEntities.Add(new MyEntity("1", 1, null));
        AllMyEntities.Add(new MyEntity("1.1", 2, 1));
        AllMyEntities.Add(new MyEntity("1.1.1", 3, 2));
        AllMyEntities.Add(new MyEntity("2", 4, null));
        AllMyEntities.Add(new MyEntity("2.1", 5, 4));

        Console.Write(GetFamilyTree(AllMyEntities).ToString());

结果

1
    1.1
        1.1.1
2
    2.1

【讨论】:

    【解决方案2】:

    for 循环内调用Foo(child)。我想这会解决你的问题。如果树很大,请不要递归。使用堆栈。

    【讨论】:

    • 是的,但仍然不完整..如何填写我的两个父亲和孩子的收藏...到最后才知道,好吧,这个父亲有这些孩子..这个父亲有这些孩子, .....
    • 这不是两个集合。是n叉树。我猜你把这个和简单的二叉树混淆了。
    • 那么考虑一棵树的深度为 100 万。在这种情况下,递归将引发堆栈溢出 :)
    【解决方案3】:

    你想做一个简单的树遍历算法。以下是伪代码中 DFS(深度优先搜索)的简单实现:

    TraverseTree(Tree t)
    {
       DoSomethingWith(t); // like writing the contents of the node to the file.
    
       if (t == null) // leaf
        return;
    
       foreach(Tree child in t.Children) // recursively traverse the children.
       {
          TraverseTree(child);
       }
    }
    

    您可以按照执行计算的顺序进行操作。查看更多详情here

    【讨论】:

    • 我在我的问题中用粗体写了请不要考虑“树”
    • @BDotA 你问的递归方法的结构,我给你写了。
    • @BDotA 你写了treeviewTreeView 是 UI 控件,另一方面 Treedata structure
    • 好吧,我也没有树结构..我应该如何使用不使用我的问题中必须使用的代码
    • 声明一个像class Node&lt;T&gt; { T Data; List&lt;Node&lt;T&gt;&gt; Children; }这样的类并从DB中递归地填充它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多