2013-07-29 217 views
-4

有沒有什麼可能的辦法我該怎麼做? nope

我知道它一見無蹤,但我可以做到這一點?

p

+2

那麼你看過http://en.wikipedia.org/wiki/Tree_traversal#爲了? –

+2

請告訴我們你已經擁有的東西以及迄今爲止嘗試過的東西。 – aevitas

+1

中序遍歷只適用於* binary *樹。如果你有N個子節點,那麼「inorder」應該是什麼意思? – Jon

回答

2

一般樹的InOrder遍歷沒有意義。由於沒有「訂單」,您應該訪問當前節點。 InOrder只對二叉樹有意義。

對於InOrder對於通用樹有意義,您必須定義當前節點應該訪問的順序。由於唯一有兩個選擇是有意義的,即首先訪問當前節點(Pre-訂單)或最後一個(後期訂單)。因此,對一般樹的InOrder並沒有多大意義。

當然,如果您的普通樹具有特定的結構,那麼InOrder可以有意義。如果你總是有第3個孩子留和所有其他人是正確的,然後你的算法是這樣的......

inorder(node) 
    if node == null then return 
    inorder(node.first) 
    inorder(node.second) 
    inorder(node.third) 
    visit(node) 
    foreach (remainingNode in RemainingNodes) 
    inorder(remainingNode) 

通用代碼擴展方法...

static public IEnumerable<Node<T>> InOrder<T>(this Node<T> thisNode) 
    { 
     var list = new List<Node<T>>(); 
     IEnumerable<Node<T>> leftNodes; 
     IEnumerable<Node<T>> rightNodes; 
     if (thisNode.Children == null) 
     { 
      leftNodes = new List<Node<T>>(); 
      rightNodes = new List<Node<T>>(); 
     } 
     else 
     { 
      leftNodes = thisNode.Children.Take((int)Math.Ceiling(thisNode.Children.Count()/2.0)).ToList(); 
      rightNodes = thisNode.Children.Skip(leftNodes.Count()).ToList(); 
     } 
     if (leftNodes.Any()) 
     { 
      foreach (var child in leftNodes) 
      { 
       list.AddRange(child.InOrder()); 
      } 
     } 
     list.Add(thisNode); 
     if (rightNodes.Any()) 
     { 
      foreach (var child in rightNodes) 
      { 
       list.AddRange(child.InOrder()); 
      } 
     } 
     return list; 
    } 
+0

在您的子節點集合上使用您的count方法來確定之前有多少個孩子以及多少個孩子去過。 – Kevin

+0

你是什麼意思一個通用版本?除了您有一組節點和一個名爲Name的屬性之外,這不會假設任何內容。將Console.WriteLine替換爲訪問該節點所需的任何操作。 – Kevin

+0

請將您的代碼發佈在您的問題陳述中。這將使它更容易幫助。 – Kevin

1

的按序遍歷要求的節點順序

  1. 留下來參觀
  2. right

對於非二叉樹,這種行爲沒有意義,因爲沒有左或右專用節點。正如凱文所說,它只有真的是有意義的執行前序遍歷或後序遍歷;然而,如果你想執行一個In-Order-esque遍歷,你可以訪問一半的子節點,這個節點,然後是另一半。不過,這並不是按照順序遍歷的精神。

例如,假設您的節點有5個孩子。這將使中序遍歷:

  1. 孩子1
  2. 孩子2
  3. 孩子3
  4. 孩子4
  5. 孩子5

(只是爲了着想的論點。從技術上說,孩子3,這可能互換,但也會出現同樣的問題)

如果孩子5,然後刪除,在序遍歷是:

  1. 孩子1
  2. 孩子2
  3. 孩子3
  4. 孩子4

和我固有順序已經改變。但是,如果你要維護兩個孩子的列表:一個是你的leftChildren,另一個是rightChildren,那麼按順序遍歷就像它在二叉樹中一樣有意義。然而,如何選擇哪個孩子進入哪個列表完全是另一個問題。

編輯:由於它似乎要繼續這個問題,您可以使用像這樣做:

public IEnumerable<Node<T>> InOrder() 
{ 
    if (Children != null) 
    { 
     for (int i = 0; i < Children.length; i++) 
     { 
      if (i == Children.length/2) 
      { 
       yield return this; 
      } 

      foreach (var node in Children[i].InOrder()) 
      { 
       yield return node; 
      } 
     } 
    } 
}