2015-06-07 76 views
1

我在嘗試刪除樹結構化對象內的項目時遇到了問題。刪除N層的嵌套集合中的項目

我的目標是如下

TreeNode 
{ 
    string name; 
    ObservableCollection<TreeNode> Children; 
} 

我想如果我遞歸遍歷樹的過程,找到我的節點,並刪除它,但我遇到了麻煩。

我做沿着

線的東西更新:

DeleteNode(ObservableCollection<TreeNode> children, TreeNode nodetodelete) 
{ 
    if(children.remove(nodetodelete)) 
    { 
     return; 
    } 
    else 
    { 
     foreach(var child in children) 
     { 
      DeleteNode(child, nodetodelete); 
     } 
    } 
} 

我知道當我在寫,我最終會遇到操作異常,同時通過有機會集合遍歷代碼正在改變。
因爲我知道確切的最大深度(我爲一個佔位符所做的),所以我可以構建一個巨大的循環變化,但看起來非常糟糕。 。 。 。
任何人都可以指向一個更好的大方向。我有點懷疑我的數據結構是否是這個原因。

更新:

這看起來有點可怕的代碼氣味,但我得到了遞歸的「工作」 拋出一個異常,當我發現我的節點。

DeleteNode(children, nodetodelete) 
    { 
     if(children.remove(nodetodelete) 
     { 
      throw FoundException(); 
     } 
     else 
     { 
      foreach(var child in children) 
      { 
       DeleteNode(child, nodetodelete) 
      } 
     } 
    } 

是否有任何其他突破遞歸的方式。

+0

您是否事先知道該節點只會在樹中出現一次? –

+0

@Andrew如果你正在談論重複,那麼可能會有重複,因爲在某個級別上,我有一個佔位符節點來將項目組合在一起。 –

+0

你可以發佈你的實際,確切的代碼?你在這裏發佈的內容甚至不會編譯。 –

回答

4

我會通過一個小的變化,以我的設計處理這個(假設你的問題的片段是一類僞代碼):

TreeNode 
{ 
    string name; 
    TreeNode Parent; 
    ObservableCollection<TreeNode> Children; 

    public void Delete() 
    { 
     Parent.Children.Remove(this); 
    } 
} 

這使得多一點點對你的工作保持一個額外的在操作對象圖時引用,但在執行刪除操作時可以節省大量工作量和代碼,如上所示。

你沒有展示你如何構建TreeNode s,但我會爲構造函數的子參數創建父類和集合。

+0

一個非常優雅的解決方案! – viperguynaz

0

只要不更改原始集合,您就可以安全地迭代子節點的集合並將其刪除。這可以通過創建一個集合的數組並對其進行迭代來完成。

DeleteNode(ObservableCollection<TreeNode> children, TreeNode nodetodelete) 
{ 
    if (children.remove(nodetodelete)) 
    { 
     return; 
    } 
    else 
    { 
     foreach (var child in children.ToArray()) 
     { 
      // If anything is deleted in the collection, it will not break the iteration here, as we are iterating over an Array and not "children" 
      DeleteNode(child, nodetodelete); 
     } 
    } 
} 

這將創建一個新的集合供您迭代。如果從children中刪除子節點,則foreach循環不會引發異常。這是因爲原始集合發生了變化,而我們重複了次要集合。