-2

假设我们有一个具有 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 应用程序很有用,我们单击一个节点,它运行此方法一次并收集它需要的数据,现在我需要编写另一个方法,利用上述方法的有用行一次抓取所有东西并编写让我们说一个文件的全部信息。

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

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

4

3 回答 3

1

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

自相关实体(Node)

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
于 2012-08-09T18:52:51.350 回答
1

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

于 2012-08-09T18:21:45.183 回答
1

你想做一个简单的树遍历算法。这是伪代码中 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);
   }
}

您可以按照执行计算的顺序进行操作。在此处查看更多详细信息

于 2012-08-09T18:21:47.910 回答