2017-10-04 49 views
0

我试图创建一个树状结构。每个班级都有一个父级字段和子级列表,与父级班级是同一班级。基本的东西。C# - 基于深度值和列表索引创建树状结构

这里是我正在使用的类的基本版本。

public class TreeElement { 
    public string name; 
    public int depth; 
    public int id; 

    public TreeElement parent; 
    public List<TreeElement> children = new List<TreeElement>(); 
} 

现在,当我得到初始数据时,我将所有这些类都列入列表中。我的树视图中的每个项目都在一个大列表中,我可以继续进行的是项目的深度值和索引。因此,该列表将基本上是这个样子:

(0) -1 
(1) |- 0 
(2)  |-- 1 
(3)  |-- 1 
(4)  | |-- 2 
(5)  |-- 1 

(x)表示在列表中的索引。其余的数字是深度值。

现在我的实际问题。我很难根据这些值制作我自己的列表,而且我基本上只知道每个孩子的单个项目被添加到哪里并且兄弟姐妹会被忽略。我真的找不到将这些考虑在内的方法。

这里是我到目前为止的代码(这可能是这个可怕的错误):

private List<TreeElement> GenerateTreeStructure(List<TreeElement> baseList) 
{ 
    // Base list is the list I get provided with. 
    List<TreeElement> newList = new List<TreeElement>(); 
    TreeElement root = null; 
    TreeElement previousFolder = null; 
    int previousdepth = -99; 

    for (int i = 0; i < baseList.Count; i++) 
    { 
     TreeElement currentResource = baseList[i]; 
     if (currentResource.depth == -1 && ShowRootFolder) // The root folder. 
     { 
      root = currentResource; 
      // (Name, depth, parent) 
      newList.Add(new TreeElement("Root", currentResource.depth, null)); 
      previousFolder = root; 
      previousdepth = root.depth; 
     } 
     else if (!ShowRootFolder && currentResource.depth <= 0) 
     { 
      // If root folder is not shown, take all the children of the root folder instead. 
      if (currentResource.depth != -1) 
      { 
       previousFolder = new TreeElement(currentResource.name, currentResource.depth, null); 
       previousdepth = previousFolder.depth; 
       newList.Add(previousFolder); 
      } 
     } 
     else 
     { 
      if (currentResource.depth > previousdepth) 
      { 
       TreeElement newResource = new TreeElement(currentResource.name, currentResource.depth, null); 
       previousFolder.children.Add(newResource); 
       previousdepth = currentResource.depth; 
       previousFolder = newResource; 
      } 
     } 
    } 

    return newList; 
} 

我希望解释我的问题。我一直坚持这一段时间,我希望能得到一些帮助!

谢谢

回答

1

你为什么要从GenerateTreeStructure函数返回TreeElement的列表有点困惑?你在做一个树形结构吗?你应该只返回rootnode?无论如何,这需要一个具有深度值的列表,并制作一棵树:

public static TreeElement GenerateTreeStructure(List<TreeElement> baseList) 
{ 
    TreeElement root = null; 
    if (baseList == null || baseList.Count == 0) return root; 

    int baseIdx = -1; 

    TreeElement prevNode = null; 
    TreeElement parent = null; 

    while (baseIdx < baseList.Count - 1) 
    { 
     baseIdx++; 
     TreeElement item = baseList[baseIdx]; 

     if (item.depth == -1) 
     { 
      root = new TreeElement("root", -1, null); 
      prevNode = root; 
      continue; 
     } 

     if (item.depth == prevNode.depth) parent = prevNode.parent; // same level as prevNode 
     else if (item.depth > prevNode.depth) parent = prevNode; // deeper 
     else              // shallower 
     { 
      parent = prevNode.parent; 
      while (parent.depth >= item.depth) parent = parent.parent; 
     } 

     TreeElement newNode = new TreeElement(item.name, item.depth, parent); 
     parent.children.Add(newNode); 
     prevNode = newNode; 
    } 

    return root; 
} 

// to test 
void Traverse(TreeElement branch, int depth) 
{ 
    log(new string('\t', depth) + branch.name); 
    foreach (var subBranch in branch.children) Traverse(subBranch, depth+1); 
} 

Traverse(root, 0); 
+0

这正是我想要的,谢谢!并澄清我为什么返回一个列表:我需要输入一个列表到树视图显示。但我只是简单地将它转换成使用你的代码返回一个列表。 – Hertzole

1

我发现了两个逻辑错误。下面是固定码:

// Base list is the list I get provided with. 
     List<TreeElement> newList = new List<TreeElement>(); 
     TreeElement root = null; 
     TreeElement previousFolder = null; 
     int previousdepth = -99; 

     for (int i = 0; i < baseList.Count; i++) 
     { 
      TreeElement currentResource = baseList[i]; 
      if (currentResource.depth == -1 && ShowRootFolder) // The root folder. 
      { 
       root = new TreeElement("Root", currentResource.depth, null); 
       // (Name, depth, parent) 
       newList.Add(root); 
       previousFolder = root; 
       previousdepth = root.depth; 
      } 
      else if (!ShowRootFolder && currentResource.depth <= 0) 
      { 
       // If root folder is not shown, take all the children of the root folder instead. 
       if (currentResource.depth != -1) 
       { 
        previousFolder = new TreeElement(currentResource.name, currentResource.depth, null); 
        previousdepth = previousFolder.depth; 
        newList.Add(previousFolder); 
       } 
      } 
      else 
      { 
       if (currentResource.depth > previousdepth) 
       { 
        TreeElement newResource = new TreeElement(currentResource.name, currentResource.depth, previousFolder); 
        previousFolder.children.Add(newResource); 
        previousdepth = currentResource.depth; 
        previousFolder = newResource; 
       } 
      } 
     } 

     return newList; 

在第一个“if”语句创建新的根,但没有将其分配到根对象,因此没有将其分配给previousFolder对象,你在最后用“如果”语句。此外,您没有将previousFolder对象传递给最后if语句中的TreeElement的构造函数,如果您尝试使用父字段从底部转到根元素,则会导致问题。

P.S.代码很奇怪,看起来你刚刚开始学习。如果我们正在谈论树结构,我会建议阅读Composite pattern以创建一棵树,并与Visitor pattern一起访问它。

+0

感谢您的修复。我做了一些测试后,我忽略了这个问题,错过了修复。关于“奇怪的代码”,这可能是因为这是我在这些条件下第一次创建树视图,而现在我只是在测试东西。对于'这个',是的,我正在学习,但我会向你保证我有几年的C#经验,并且我知道如何创建一个树形视图...如果我知道所有类是什么,并且他们是以合理的方式给我的。说实话,你提供的这些链接没有什么帮助,但我仍然很感激他们!他们是一些有趣的读物! – Hertzole