Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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/0/drupal/3.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#_List_Recursion - Fatal编程技术网

C# 递归搜索嵌套列表;返回父母

C# 递归搜索嵌套列表;返回父母,c#,list,recursion,C#,List,Recursion,这是这篇文章的后续文章: 我一直在尝试修改代码,使其允许我返回任何子项所在位置的父项,但由于某些原因,该函数的递归方面在我的大脑中不太顺畅 在一个完美的世界中,我希望能够指定要返回多少父节点,但即使是直接节点也很好 public static AccessibleTreeItem Find(AccessibleTreeItem node, string name) { if (node == null) return null;

这是这篇文章的后续文章:

我一直在尝试修改代码,使其允许我返回任何子项所在位置的父项,但由于某些原因,该函数的递归方面在我的大脑中不太顺畅

在一个完美的世界中,我希望能够指定要返回多少父节点,但即使是直接节点也很好

    public static AccessibleTreeItem Find(AccessibleTreeItem node, string name)
    {

        if (node == null)
            return null;

        if (node.name == name)
            return node;

        foreach (var child in node.children)
        {
            var found = Find(child, name);
            if (found != null)
                return found;
        }

        return null;
    }
谢谢大家花时间看一看

编辑:例如,我希望能够调用Find(node、name、parentIndex)或类似的函数,以传递一个值,该值表示返回的项可以找到的父级的数量

编辑2:为了澄清,我希望能够告诉函数查找特定名称和父索引。该函数将定位要搜索的节点,然后沿“树”遍历指定数量的级别,最后返回该对象

所以如果我们打电话

    Find(node, "Test", 2)
正在搜索的值位于:

    node.children[0].children[3].children[2].children[1]
然后,函数应返回位于以下位置的对象:

    node.children[0].children[3]

啊哈。。。因此,请尝试向下传递一个名为“ANCESTORCUNT”的(正)整数(1代表父母,2代表祖父母,3代表曾祖父母,等等)。。。如果found返回true(非null)且ancestorCount==0返回此值,则在返回找到的子项之前减小ancestorCount

这对你有意义吗?我将在大约10分钟内编辑这篇文章,将其放入psuedocode(至少)

干杯。基思


编辑:至少提供某种代码

这不是编译的,更不用说测试了。。。因此我根本不确定我的情况是否正确。。。正如本所指出的,我可能会把它完全倒过来;-)这是一种我通常需要调试一段时间才能正确进行的事情。。。但我认为“我很接近”,核心思想就在那里。。。我将把微调留给实现者。。。你;-)

。。。但我可以看到,我现在必须实现Node,只是为了满足我自己对算法正确性的好奇心。唉

干杯。基思


EDIT2:

嗯,这对我来说很有用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Tree
{
    class Node {
        private List<Node> _kids = new List<Node>();
        public string Name { get; set; }
        public List<Node> Children { get { return _kids; } }
        public void Add(Node child) { _kids.Add(child); }
        public override string ToString() { return Name; }
    }

    class Program
    {
        Node _root;

        static void Main(string[] args) {
            new Program().Run();
            Console.Write("Press any key ...");
            Console.ReadKey();
        }

        Program() {
            _root = GenerateTree();
        }

        static Node GenerateTree()
        {
            // Gen0
            Node root = new Node() { Name = "Great-grandpa Jimmy Joe Jim-Bob John Keith Luke Duke" };
            // Add Gen1 to Gen0
            root.Add(new Node() { Name = "GrandUncle Joe Duke" });
            Node grandDad = new Node() { Name = "Granddad Jimmy Duke" };
            root.Add(grandDad);

            // Add Gen2 to Gen1
            grandDad.Add(new Node() { Name = "Uncle Jim" });
            grandDad.Add(new Node() { Name = "Uncle Bob" });
            Node dad = new Node() { Name = "Dad John" };
            grandDad.Add(dad);

            // Add Gen3 to Gen2
            dad.Add(new Node() { Name = "Brother Luke" });
            dad.Add(new Node() { Name = "Keith" });

            return root;
        }

        void Run() {
            Console.WriteLine("My Great-granddad is: " + Find("Keith", 3));
            Console.WriteLine("My granddad is: " + Find("Keith", 2));
            Console.WriteLine("My dad is: " + Find("Keith", 1));
            Console.WriteLine();
            Console.WriteLine("Brother Luke's Dad is: " + Find("Brother Luke", 1));
            Console.WriteLine("Uncle Bob's dad is: " + Find("Uncle Bob", 1));
            Console.WriteLine("Uncle Jim's granddad is: " + Find("Uncle Jim", 2));
            Console.WriteLine();
            Console.WriteLine("Lunil's mom is: " + Find("Lunil", 1));
            Console.WriteLine();
        }


        string Find(string targetName, int anticedentLevel) {
            Node n = Find(_root, targetName, ref anticedentLevel);
            return n!=null ? n.ToString() : "#NOT_FOUND#";
        }

        private static Node Find(Node node, string targetName, ref int ancenstorCount) {
            if ( node == null )
                return null;
            if ( ancenstorCount == 0 ) // we've already found the right level to return
                return node;
            if ( node.Name == targetName )
                return node;
            foreach ( Node child in node.Children ) {
                var found = Find(child, targetName, ref ancenstorCount);
                if ( found != null ) {
                    if ( ancenstorCount == 0 )
                        return found;
                    --ancenstorCount;
                    return node; // return any non-null 
                }
            }
            return null;
        }

    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
名称空间树
{
类节点{
私有列表_kids=新列表();
公共字符串名称{get;set;}
公共列表子项{get{return\u kids;}
公共void添加(节点子节点){u kids.Add(子节点);}
公共重写字符串ToString(){return Name;}
}
班级计划
{
节点_根;
静态void Main(字符串[]参数){
新程序().Run();
控制台。写入(“按任意键…”);
Console.ReadKey();
}
程序(){
_root=GenerateTree();
}
静态节点GenerateTree()
{
//Gen0
Node root=new Node(){Name=“曾祖父吉米·乔·吉姆·鲍勃·约翰·基思·卢克·杜克”};
//将Gen1添加到Gen0
Add(新节点(){Name=“grandbulke Joe Duke”});
Node grandad=new Node(){Name=“grandad Jimmy Duke”};
root.Add(祖父);
//将Gen2添加到Gen1
Add(新节点(){Name=“叔叔Jim”});
Add(新节点(){Name=“Bob叔叔”});
Node dad=new Node(){Name=“dad John”};
爷爷。加上(爸爸);
//将Gen3添加到Gen2
Add(新节点(){Name=“Brother Luke”});
Add(新节点(){Name=“Keith”});
返回根;
}
无效运行(){
Console.WriteLine(“我的曾祖父是:”+Find(“基思”,3));
Console.WriteLine(“我爷爷是:”+Find(“基思”,2));
Console.WriteLine(“我爸爸是:”+Find(“基思”,1));
Console.WriteLine();
Console.WriteLine(“卢克兄弟的爸爸是:”+Find(“卢克兄弟”,1));
Console.WriteLine(“鲍勃叔叔的爸爸是:”+Find(“鲍勃叔叔”,1));
Console.WriteLine(“吉姆叔叔的爷爷是:”+Find(“吉姆叔叔”,2));
Console.WriteLine();
Console.WriteLine(“Lunil的妈妈是:”+Find(“Lunil”,1));
Console.WriteLine();
}
字符串查找(字符串targetName,int anticedentLevel){
节点n=查找(_根,targetName,ref anticedentLevel);
返回n!=null?n.ToString():“#未找到#”;
}
私有静态节点查找(节点节点,字符串targetName,ref int antenstorcount){
if(node==null)
返回null;
if(anstorcount==0)//我们已经找到了要返回的正确级别
返回节点;
if(node.Name==targetName)
返回节点;
foreach(Node.Children中的节点子节点){
var found=Find(子项、targetName、ref-antenstorcount);
如果(找到!=null){
如果(ancenstorCount==0)
发现退货;
--安森托尔Count;
return节点;//返回任何非空值
}
}
返回null;
}
}
}
输出

My Great-granddad is: Great-grandpa Jimmy Joe Jim-Bob John Keith Luke Duke My granddad is: Granddad Jimmy Duke My dad is: Dad John Brother Luke's Dad is: Dad John Uncle Bob's dad is: Granddad Jimmy Duke Uncle Jim's granddad is: Great-grandpa Jimmy Joe Jim-Bob John Keith Luke Duke Lunil's mom is: #NOT_FOUND# Press any key ... 我的曾祖父是:曾祖父吉米·乔·吉姆·鲍勃·约翰·基思·卢克·杜克 我爷爷是:爷爷吉米·杜克 我爸爸是:爸爸约翰 卢克兄弟的爸爸是:爸爸约翰 鲍勃叔叔的爸爸是:爷爷吉米·杜克 吉姆叔叔的祖父是:曾祖父吉米·乔·吉姆·鲍勃·约翰·基思·卢克·杜克 鲁尼尔的妈妈是:#没找到## 按任意键。。。 。。。虽然在现实世界中,您可能会“只是”在每个节点中使用父引用来实现它,因为这样更简单。。。我不知道什么是“AccessibleTreeItem”,但如果它有父属性,那么循环到node.Pa就很容易了 My Great-granddad is: Great-grandpa Jimmy Joe Jim-Bob John Keith Luke Duke My granddad is: Granddad Jimmy Duke My dad is: Dad John Brother Luke's Dad is: Dad John Uncle Bob's dad is: Granddad Jimmy Duke Uncle Jim's granddad is: Great-grandpa Jimmy Joe Jim-Bob John Keith Luke Duke Lunil's mom is: #NOT_FOUND# Press any key ...
public AccessibleTreeItem GetParent(AccessibleTreeItem node, int depth)
{
    if(depth <= 1) // can't go higher than 1
    {
        return node.Parent;
    }
    else
    {
        return GetParent(node.Parent, depth-1);
    }
}