啊哈...所以尝试传递 byref 一个名为“ancestorCount”的(正)整数(1 表示父母,2 表示祖父母,3 表示曾祖父,等等)。 ..如果找到返回true(非空)并且祖先计数==0返回这个,否则在返回找到的孩子之前减少祖先计数......
这对你有意义吗?我将在大约 10 分钟内编辑这篇文章,以将其放入伪代码(至少)。
干杯。基思。
编辑:至少提供某种代码。
这不是编译的,更不用说测试了...因此我完全不确定我的条件是否正确...正如 Ben 指出的那样,我可能完全倒退了 ;-)这是一种我通常需要调试一段时间才能正确的事情......但我确实认为“我已经很接近了”,核心思想就在那里......我将把微调留给实施者......你;-)
public 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);
if ( found != null ) {
if ( ancenstorCount == 0 )
return found;
--ancenstorCount;
return node; // return any non-null
}
}
return null;
}
...但是我可以看到我现在必须实现 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;
}
}
}
输出
我的曾祖父是:曾祖父 Jimmy Joe Jim-Bob John Keith Luke Duke
我的爷爷是:爷爷吉米杜克
我爸爸是:爸爸约翰
卢克弟兄的爸爸是:约翰爸爸
鲍勃叔叔的父亲是:吉米·杜克爷爷
吉姆叔叔的祖父是:曾祖父吉米乔吉姆鲍勃约翰基思卢克杜克
Lunil 的妈妈是:#NOT_FOUND#
按任意键 ...
...尽管在现实世界中,您可能“只是”在每个节点中使用父引用来实现它,仅仅是因为这更简单...并且对其他事情有用。