递归函数问题

时间:2014-11-28 12:32:01

标签: c# function recursion

我正在使用安装位置的树结构:每个可能包含子Installation51,这些也可以包含子等等。我有以下功能:

public JsonResult GetInstPlacesTree()
{
    InstallationPlaceModel ipm = new InstallationPlaceModel();
    var dataContext = ipm.getRootInstallationPlaces();

    var instPlaces = from ip in dataContext.installationPlaces
                    select new
                    {
                        id = ip.installationPlace.id,
                        Name = ip.installationPlace.mediumDescription,
                    };

    return Json(instPlaces, JsonRequestBehavior.AllowGet);
}

此函数仅返回树的根级别。

我有两种工作方法:

  • 一个返回根安装位置;
  • 另一个返回给定安装位置的子项;

它们都返回IEnumerable变量。

getRootInstallationPlaces();
getChildInstallationPlaces(id);

如何调用所有安装位置和相应的孩子?

我尝试了GetInstPlacesTree()函数的替代方法:

private IEnumerable<TreeViewItemModel> GetDefaultInlineData()
{
    InstallationPlaceModel ipm = new InstallationPlaceModel();
    List<TreeViewItemModel> fullTree = new List<TreeViewItemModel>();
    var gipo = ipm.getChildInstallationPlaces(currentInstallationPlace.InstallationPlaceId);
    List<TreeViewItemModel> childTree = new List<TreeViewItemModel>();
    if (gipo.installationPlaces.Count() > 0)
    {
        foreach (wsInstallationPlace.installationPlaceOutput child in gipo.installationPlaces)
        {
            TreeViewItemModel childTreeItem = new TreeViewItemModel
            {
                Text = child.installationPlace.mediumDescription,
                Id = child.installationPlace.id
            };
            childTree.Add(childTreeItem);
        }
    }
    TreeViewItemModel fatherTreeItem = new TreeViewItemModel
    {
        Text = currentInstallationPlace.InstallationPlaceMediumDescription,
        Id = currentInstallationPlace.InstallationPlaceId,
        Items = childTree
    };
    fullTree.Add(fatherTreeItem);
    return fullTree;
}

任何帮助?

3 个答案:

答案 0 :(得分:1)

我认为以下内容应该是您所追求的。从本质上讲,它使您的初始方法几乎保持原样,但它通过递归调用填充每个顶级的子Items

递归调用抓取子节点并将每个子节点添加到要返回的List<TreeViewItemModel>,但是他们的子节点又通过调用递归函数来填充。当没有孩子离开时,递归将结束:

public JsonResult GetInstPlacesTree()
{
    InstallationPlaceModel ipm = new InstallationPlaceModel();
    var dataContext = ipm.getRootInstallationPlaces();

    var instPlaces = from ip in dataContext.installationPlaces
                        select new TreeViewItemModel 
                        {
                            id = ip.installationPlace.id,
                            Name = ip.installationPlace.mediumDescription,
                            Items = getChildInstallationPlacesRecursive(ip.installationPlace.id, ipm)
                        };

    return Json(instPlaces, JsonRequestBehavior.AllowGet);
}

public List<TreeViewItemModel> getChildInstallationPlacesRecursive(int id, InstallationPlaceModel ipm)
{
    List<TreeViewItemModel> children = new List<TreeViewItemModel>();

    var gipo = ipm.getChildInstallationPlaces(id);

    foreach (wsInstallationPlace.installationPlaceOutput child in gipo.installationPlaces)
    {
        children.Add(new TreeViewItemModel
        {
            Text = child.installationPlace.mediumDescription,
            Id = child.installationPlace.id,
            Items = getChildInstallationPlacesRecursive(child.installationPlace.id, ipm)
        });
    }

    return children;
}

答案 1 :(得分:0)

为了使它递归,你必须认为孩子的位置同时是他们自己孩子的根,然后你可以为他们调用相同的功能。

private IEnumerable<TreeViewItemModel> RecursivePlaces(InstallationPlace root){
     var output = new List<TreeViewItemModel>();
     output.add(new TreeViewItemModel
        {
            Text = root.installationPlace.mediumDescription,
            Id = root.installationPlace.id
        });         

     foreach(var child in root.installationPlaces)
       output.AddRange(RecursivePlaces(child));

     return output;
}

//Initial call
RecursivePlaces(ipm.getRootInstallationPlace());

答案 2 :(得分:-1)

您可以使用以下方法在不递归的情况下解决此问题。我用某种伪代码编写它,所以你会明白我建议完成什么,我没有使用你确切的函数名称和结构和类......

queue = new List<>();
queue.Add(initialInstallation);
retVal = new List<>();

while (queue.Count > 0) {
    retVal.Add(queue[0].GetData());
    queue.Add(queue[0].GetChildren());
    queue.Remove(0);
}

return retVal;