最も簡単な方法は、再帰を使用することです。
あなたのツリーにはT型のアイテムが格納されており、そのタイプはIEquatable<T>
を実装しているとしましょう。
まず、のは非常に基本的な木のクラスを書いてみましょう:
public sealed class Node<T>
{
public Node(T value) { Value = value; }
public T Value { get; }
public IEnumerable<Node<T>> Children => _children;
public void Add(Node<T> child)
{
_children.Add(child);
}
readonly List<Node<T>> _children = new List<Node<T>>();
}
今、私たちは非常に単純再帰を使用して、そのツリーを検索する方法を書くことができます。 これは、見つかった場合は指定された値を含む最初のノードを返します。見つからない場合はnullを返します。
public static Node<T> Find<T>(Node<T> root, T target) where T: IEquatable<T>
{
if (root.Value != null && root.Value.Equals(target))
return root;
foreach (var child in root.Children)
{
var found = Find(child, target);
if (found != null)
return found;
}
return null;
}
それはターゲットに一致するすべてのノードを返すために、これを適応するのは簡単です:デモ目的のために
public static IEnumerable<Node<T>> FindAll<T>(Node<T> root, T target) where T : IEquatable<T>
{
if (root.Value != null && root.Value.Equals(target))
yield return root;
foreach (var child in root.Children)
{
var found = FindAll(child, target);
foreach (var item in found)
yield return item;
}
}
は、ここでコンパイルコンソールアプリケーションです。それにはmakeTree()
メソッドが含まれています。このメソッドでは、各ノードに5つの子がある深さ4のツリーを作成します。
次に、Find<T>(Node<T> root, T target)
を使用して、指定されたターゲット値を見つけるためにツリーを再帰的に検索します。 1つは成功し、もう1つは失敗します。
using System;
using System.Collections.Generic;
namespace Demo
{
public sealed class Node<T>
{
public Node(T value) { Value = value; }
public T Value { get; }
public IEnumerable<Node<T>> Children => _children;
public void Add(Node<T> child)
{
_children.Add(child);
}
readonly List<Node<T>> _children = new List<Node<T>>();
}
class Program
{
static void Main()
{
var root = makeTree(1, 1, 4, 5);
lookFor(root, "3.4");
lookFor(root, "6.3");
}
static void lookFor<T>(Node<T> root, T target) where T: IEquatable<T>
{
var found = Find(root, target);
Console.WriteLine(found != null ? $"Found {target}" : $"Did not find {target}");
}
public static Node<T> Find<T>(Node<T> root, T target) where T: IEquatable<T>
{
if (root.Value != null && root.Value.Equals(target))
return root;
foreach (var child in root.Children)
{
var found = Find(child, target);
if (found != null)
return found;
}
return null;
}
static Node<string> makeTree(int id1, int id2, int depth, int nChildren)
{
var root = new Node<string>($"{id1}.{id2}");
if (depth == 0)
return root;
for (int i = 0; i < nChildren; ++i)
root.Add(makeTree(id1+1, i+1, depth-1, nChildren));
return root;
}
}
}
陽気な回答、大変感謝しています。 –