2015-01-11 44 views
2

我正在嘗試使用隊列遍歷樹中的所有葉節點。 但我無法獲得任何輸出。遍歷樹中的所有葉節點C#

class MyNode<T> 
{ 
    public T Data { get; set; } 
    public MyNode<T> Parent { get; set; } 
    public List<MyNode<T>> Children = new List<MyNode<T>>(); 
    public MyNode(T data, MyNode<T> parent) 
    { 
     Data = data; 
     Parent = parent; 
    } 

    public override string ToString() 
    { 
     if (Children == null) return Data.ToString(); 
     return string.Format("{0} {1} ", Data.ToString(), Children.ToString()); 
    } 

} 

節點可以有任意數量的子節點。這是我寫的打印所有葉節點的內容。我什麼也得不到,我想只有最後一行Console.WriteLine(「」);被執行,但我不明白爲什麼。

public static void PrintSentence(MyNode<string> root) 
    { 
     if (root == null) // Return when the tree is empty. 
      return; 

     Queue<MyNode<string>> nodeQueue = new Queue<MyNode<string>>(); 
     nodeQueue.Enqueue(root); 

     MyNode<string> currentNode = root; 

     while (nodeQueue.Count != 0) 
     { 
      currentNode = nodeQueue.Peek(); 
      nodeQueue.Dequeue(); 

      if (currentNode.Children == null) // Print strings only when the current node is a leaf node. 
       Console.Write(currentNode.Data + " "); 

      for (int i = 0; i < currentNode.Children.Count(); i++) 
       nodeQueue.Enqueue(currentNode.Children[i]); 
     } 

     Console.WriteLine(""); 

    } 

感謝您的任何幫助。 樹類是這樣的,實際上我無法在任何地方找到我的調試窗口... 我只寫了PrintSentence方法,其他的東西是其他人寫的。

class Tree<T> 
{ 
    public MyNode<T> Root { get; set; } 
    public Tree(MyNode<T> root) { Root = root; } 
    public override string ToString() 
    { 
     if (Root == null) return ""; 
     return Root.ToString(); 
    } 
} 
+0

能否請您提供更多的信息 - 尤其是你的樹?另外,當你在調試器中執行代碼時,會執行哪些代碼,哪些不執行? –

回答

3

你需要替換此行

if (currentNode.Children == null)

與此

if (currentNode.Children.Count == 0)

這將檢查列表沒有任何元素(沒有孩子)。既然你總是初始化你的列表,它將不會爲空,即使它是空的。

+0

我懂了!非常感謝! – Ahaha

+1

請注意,「它永遠不會爲空」不是真的,因爲OP會將該列表公開,並且可以很容易地將其設置爲null。很好的回答將包括避免這種情況的建議(即通過不公開列表並且爲'IEnumerable '添加r/o屬性來讀取兒童列表+方法添加/設置兒童)。 –

0

單獨的節點遍歷和遍歷操作是這樣的:

我有選擇遞歸,因爲樹深recusrion通常不是問題,你不需要太多內存queueu。

public static class MyNodeExt<T> 
{ 
    IEnumerable<T> TraverseLeafs<T>(this MyNode<T> node) 
    { 
     if (node.Children.Count == 0) 
      yield return node; 
     else 
     { 
      foreach(var child in root.Children) 
      { 
       foreach(var subchild in child.TraverseLeafs()) 
       { 
        yield return subchild; 
       } 
      } 
     } 
    } 
} 

和獨立遍歷操作:

public static void PrintSentence(MyNode<string> root) 
{ 
    foreach(var node in root.TraverseLeafs()) 
    { 
     Console.Write(node .Data + " "); 
    }  
} 
0

通用的解決方案:

public static class Hierarchy 
{ 
    /// <summary> 
    /// Gets the collection of leafs (items that have no children) from a hierarchical collection 
    /// </summary> 
    /// <typeparam name="T">The collection type</typeparam> 
    /// <param name="source">The sourceitem of the collection</param> 
    /// <param name="getChildren">A method that returns the children of an item</param> 
    /// <returns>The collection of leafs</returns> 
    public static IEnumerable<T> GetLeafs<T>(T source, Func<T, IEnumerable<T>> getChildren) 
    { 
     if (!getChildren(source).Any()) 
     { 
      yield return source; 
     } 
     else 
     { 
      foreach (var child in getChildren(source)) 
      { 
       foreach (var subchild in GetLeafs(child, getChildren)) 
       { 
        yield return subchild; 
       } 
      } 
     } 
    } 
} 

用法:

var leafs = Hierarchy.GetLeafs(root, (element) => element.Children);