2017-10-04 78 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