删除第N级嵌套集合中的项目

时间:2015-06-07 03:56:01

标签: c# recursion

我在尝试删除树状结构对象中的项目时遇到了麻烦。

我的目标如下

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);
        }
    }
}

我在编写代码时意识到,在迭代通过可能被更改的集合时,我最终会遇到操作异常。
我可以建立一个for循环的巨大变化,因为我确切知道最大深度(我为一个占位符所做的),但这看起来非常糟糕。 。 。 。
任何人都可以指出我更好的总体方向。我有点想知道我的数据结构是否是原因造成的。

更新

这看起来很糟糕,有点代码味道,但我得到了“工作”的递归 当我找到我的节点时抛出异常。

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

还有其他方法可以突破递归。

2 个答案:

答案 0 :(得分:4)

我会通过对我的设计进行一些小改动来处理这个问题(假设你的问题中的代码片段是一个类的伪代码):

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

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

这样可以在操作对象图时为您提供额外的参考,但在执行删除操作时可以节省大量精力和代码,如上所示。

你还没有展示你是如何构建TreeNode的,但是我会为构造函数的子参数创建父元素和集合。

答案 1 :(得分: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循环不会抛出异常。这是因为我们更改了原始集合,而我们遍历了一个辅助集合。