c#中的递归树遍历问题

时间:2016-03-29 08:26:05

标签: c# entity-framework linq tree

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

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的所有孩子都无法访问。

我的方法有什么问题?

1 个答案:

答案 0 :(得分:2)

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

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)代替。