【问题标题】:Issue with recursive tree traversal in c#c#中递归树遍历的问题
【发布时间】:2016-03-29 16:56:04
【问题描述】:

我有以下格式的树结构数据:

H1    
    H1 - 1
        H1 - 1 - 1
            H1 - 1 - 1 - 1
                H1 - 1 - 1 - 1 -1
                    H1 - 1 - 1 - 1 -1 - 1
        H1 - 1 - 2
        H1 - 1 - 3
    H1 - 2
        H1 - 2 - 1
        H1 - 2 - 2

H2    
H3    
    H3 - 1
        H3 - 1 - 1
            H3 - 1 - 1 - 1
                H3 - 1 - 1 - 1 - 1
            H3 - 1 - 1 - 2
        H3 - 1 - 2
        H3 - 1 - 3
    H3 - 2

我必须通过传递子项的ID 来检查上述树中是否存在某个项目,因此我需要遍历上述树中的每个项目。到目前为止,我已经编写了以下递归方法:

public bool CheckIfChildItemExists(Item parentItem, long childItemId)
{
    var isChildExisting = false;
    foreach (Item item in parentItem.Children)
    {
        if (item == context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault() || item.Children.Contains(context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault()))
        {
            isChildExisting = true;
            return isChildExisting;
        }
        else
        {
            return CheckIfChildItemExists(item, childItemId);
        }
    }
    return isChildExisting;
}

使用上述方法:

  • 根项目H1, H2, H3 可访问。
  • H1H1 -1H1 - 1 - 1H1 - 1 - 1 -1 等)的所有分支都可以访问。
  • H1 - 2 - 1H1 - 2 - 2 不可访问,它们没有被遍历。不过他们的父项 H1 - 2 是可以访问的。
  • H3 的所有子代均不可访问。

我的方法做错了什么?

【问题讨论】:

  • 看起来你的 List 不是单根/父,你必须处理这种情况。
  • @HariPrasad 我必须检查该项目是否存在于parentItem 的子代中,我将其传递给具有我在问题中提到的子数据的方法。 H1, H2, H3 是子项。

标签: c# entity-framework linq tree


【解决方案1】:

你要早点回来。您所做的实际上是从根到叶子最多检查一个分支,但您从不检查其他分支。

public bool CheckIfChildItemExists(Item parentItem, long childItemId)
{
    foreach (Item item in parentItem.Children)
    {
        if (item == context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault() || item.Children.Contains(context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault()))
        {
            return true;
        }
        else
        {
            var childItemExists = CheckIfChildItemExists(item, childItemId);
            if(childItemExists) return true; // else continue search in other children
        }
    }
    return isChildExisting;
}

我不确定您在if 语句中的条件是否正确。如果您的所有商品都符合搜索条件,您可以尝试使用该代码。您应该为每个根项运行此过程,或者将人工根项传递给函数。

public bool CheckIfChildItemExists(Item parentItem, long childItemId)
{
    if(parentItem.ItemID == childItemId && parentItem.IsActive) return true;
    foreach (Item item in parentItem.Children)
    {
        var childItemExists = CheckIfChildItemExists(item, childItemId);
        if(childItemExists) return true; // else continue search in 
    }
    return false;
}

item == context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault() 中,您实际上是在比较两个对象,为什么不只检查item 对象的条件呢?此外,您可以改用context.Items.FirstOrDefault(x => x.ItemID == childItemId && x.IsActive)

【讨论】:

  • 我添加了item == context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault() 条件来检查循环中的当前Item 是否是我们正在搜索的ChidItem,如果我删除这个条件,那么根级别的父母H1, H2, H3 是如果正在搜索的ChildItemH1, H2 or H3,则被跳过并且只有他们的孩子被遍历。
  • 尽量避免检查当前节点的子/孙是否满足条件。为每个节点单独执行递归是一项工作。
猜你喜欢
  • 2021-11-03
  • 2020-05-21
  • 1970-01-01
  • 2018-07-12
  • 2014-03-11
  • 1970-01-01
  • 2017-05-11
  • 2021-05-04
  • 1970-01-01
相关资源
最近更新 更多