Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 树状分支算法_C#_Algorithm - Fatal编程技术网

C# 树状分支算法

C# 树状分支算法,c#,algorithm,C#,Algorithm,我试图创建一个函数,输入是一个ID列表,输出是一个树,其中节点基于其ID和所有父节点 每个节点都有一个父ID主页(ID:1)是根目录 函数标题类似于: public ModuleDTO GetModuleTree(List<int> ids); 提前感谢。(我假设这里的查找速度不是很重要,或者树比较小) 首先,让我们考虑为单个输入找到答案。这里一个可用的方法是尝试一个递归算法。查看树中的每个节点,找到后立即返回。一旦开始从递归返回,您将继续“向上”树,并将所有节点返回到主节点 有多

我试图创建一个函数,输入是一个ID列表,输出是一个树,其中节点基于其
ID
和所有父节点

每个节点都有一个
父ID
<代码>主页(ID:1)是根目录

函数标题类似于:

public ModuleDTO GetModuleTree(List<int> ids);
提前感谢。

(我假设这里的查找速度不是很重要,或者树比较小)

首先,让我们考虑为单个输入找到答案。这里一个可用的方法是尝试一个递归算法。查看树中的每个节点,找到后立即返回。一旦开始从递归返回,您将继续“向上”树,并将所有节点返回到主节点

有多个ID的情况就变成了只做几次,然后合并所有结果

当然,根据性能需求和更改数据结构的自由度,可以对该算法进行一些改进,也可以采取其他方法。不过,它们可能没有上述解决方案的实现那么简单和清晰。

我用以下方法解决了这个问题:

public ModuleDTO GetModulesForUser(string userName)
{
    // Returns the list of IDs
    var ids = ListOfUserModules(userName);

    var modules = GetModuleTree(null);
    var module = modules.First();

    PruneTree(module, ids);

    return module;
}

public List<ModuleDTO> GetModuleTree(ModuleDTO parentModule)
{
    int? parentID = null;

    if (parentModule != null)
    {
        parentID = parentModule.ID;
    }

    var childModules = _modules.All().Where(s => s.ParentID == parentID).Select(x => x.ToDTO());

    List<ModuleDTO> modules = new List<ModuleDTO>();

    foreach (var m in childModules)
    {
        m.ChildModules = GetModuleTree(m);
        modules.Add(m);
    }

    return modules;
}

private void PruneTree(ModuleDTO root, List<int> ids)
{
    for(int i = root.ChildModules.Count() - 1; i >= 0; i--)
    {
        PruneTree(root.ChildModules[i], ids);
        if (root.ChildModules[i].ChildModules.Count == 0)
        {
            if (!ids.Contains(root.ChildModules[i].ID))
            {
                root.ChildModules.RemoveAt(i);
            }
        }
    }
}
public ModuleDTO GetModulesForUser(字符串用户名)
{
//返回ID的列表
var id=ListOfUserModules(用户名);
var modules=GetModuleTree(null);
var module=modules.First();
PruneTree(模块,id);
返回模块;
}
公共列表GetModuleTree(ModuleToParentModule)
{
int?parentID=null;
if(parentModule!=null)
{
parentID=parentModule.ID;
}
var childModules=_modules.All()。其中(s=>s.ParentID==ParentID)。选择(x=>x.ToDTO());
列表模块=新列表();
foreach(childModules中的var m)
{
m、 ChildModules=GetModuleTree(m);
增加(m);
}
返回模块;
}
私有void PruneTree(模块化为根,列表ID)
{
对于(int i=root.ChildModules.Count()-1;i>=0;i--)
{
PruneTree(root.ChildModules[i],id);
if(root.ChildModules[i].ChildModules.Count==0)
{
如果(!ids.Contains(root.ChildModules[i].ID))
{
根.ChildModules.RemoveAt(i);
}
}
}
}

为什么输入时会返回
2
?它不是
4
的父项?您是正确的,已修复。很抱歉。:)你试过什么吗?我建议现在将其限制为一个数字(即不要尝试从
5
8
案例开始)。提示:递归深度优先搜索。我试过一些方法。主要是我很难决定是将分支添加到根节点(构建树),还是从一个完整的树开始并过滤掉节点。你有一个例子给我看吗?
public ModuleDTO GetModulesForUser(string userName)
{
    // Returns the list of IDs
    var ids = ListOfUserModules(userName);

    var modules = GetModuleTree(null);
    var module = modules.First();

    PruneTree(module, ids);

    return module;
}

public List<ModuleDTO> GetModuleTree(ModuleDTO parentModule)
{
    int? parentID = null;

    if (parentModule != null)
    {
        parentID = parentModule.ID;
    }

    var childModules = _modules.All().Where(s => s.ParentID == parentID).Select(x => x.ToDTO());

    List<ModuleDTO> modules = new List<ModuleDTO>();

    foreach (var m in childModules)
    {
        m.ChildModules = GetModuleTree(m);
        modules.Add(m);
    }

    return modules;
}

private void PruneTree(ModuleDTO root, List<int> ids)
{
    for(int i = root.ChildModules.Count() - 1; i >= 0; i--)
    {
        PruneTree(root.ChildModules[i], ids);
        if (root.ChildModules[i].ChildModules.Count == 0)
        {
            if (!ids.Contains(root.ChildModules[i].ID))
            {
                root.ChildModules.RemoveAt(i);
            }
        }
    }
}