印刷したい(リスト>ツリーリーフの各パスにc#(できれば再帰的に)
木の場合:
A
B C
D E F G H
I
私が取得したい結果は、葉のリストのリストです(Aは葉、ABDIは葉のリストです):
ABDI
ABE
ABF
ACG
ACH
foreach のようなさまざまなループを試していましたが、パス全体を取得するためにいつ印刷すればよいかわかりません。
印刷したい(リスト>ツリーリーフの各パスにc#(できれば再帰的に)
木の場合:
A
B C
D E F G H
I
私が取得したい結果は、葉のリストのリストです(Aは葉、ABDIは葉のリストです):
ABDI
ABE
ABF
ACG
ACH
foreach のようなさまざまなループを試していましたが、パス全体を取得するためにいつ印刷すればよいかわかりません。
depth-first traversalを使用する必要があります。
解決策は次のとおりです。
public class Node {
public List<Node> Children {get;set;}
public string Label {get;set;}
}
public static void Print(Node node, string result)
{
if (node.Children == null || node.Children.Count == 0)
{
Console.WriteLine(result);
return;
}
foreach(var child in node.Children)
{
Print(child, result + child.Label);
}
}
次のように呼び出します。
Print(root, root.Label);
次のようにする必要があります: (初めて ListNodes(node, "") を呼び出します。
private void ListNodes(TreeNode node, string root)
{
if (node.Nodes.Count > 0)
{
foreach (TreeNode n in node.Nodes)
{
ListNodes(n, root + node.Text);
}
}
else
{
Console.Write(" " + root + node.Text);
}
}
次のような構造があるとします。
class Node {
List<Node> Children {get;set;}
string Label {get;set;}
}
次のような再帰的な方法でパスを出力できます。
void PrintPaths (Node node, List<Node> currentPath)
{
currentPath = new List<Node>(currentPath);
currentPath.Add (node);
if (node.Children.Any()) {
foreach (var child in node.Children)
PrintPaths (child, currentPath);
} else {
//we are at a leaf, print
foreach (var n in currentPath)
Console.Write (n.Label);
Console.WriteLine ();
}
}
ルート ノードでこれを呼び出します。PrintPaths (rootnode, null);
印刷する代わりにこれらのリストを返したい場合は、追加の引数 aList<List<Node>>
をメソッドに渡し、最後に印刷する代わりに、現在のパスを結果に追加します。
var result = new List<List<Node>> ();
GetPaths (rootNode, null, result); //implementation not provided, but trivial
スタックを使用した深さ優先検索、別のクリーンな方法
push (root);
while (top ())
{
pop (top);
push (node->right);
push (node->left);
}
これは再帰的に行うことができます