您可以使用僅具有下一個指針和子指針的節點類型來表示多路樹。
該節點的next
指針用於指向下一個兄弟孩子,實現爲一個簡單的鏈接列表。
節點的child
指針用於指向節點的第一個子節點。
下面是一些演示如何將它們放在一起的示例代碼。它不包含任何錯誤處理,它不是一個完整的解決方案,但是你應該能夠編譯它並且 - 如果需要的話 - 在調試器下運行它,以便完全理解它是如何工作的。
我還添加了一個枚舉示例來展示如何遍歷樹節點。你可能想要玩這個來產生不同順序的結果。如果使用枚舉對於你所需要的來說太複雜,你將需要編寫自己的簡單recusive方法來訪問所有節點。
請注意,在本例中節點類型是通用的,我只用它來保存字符串數據。如果您的不需要想要一個通用類型,您可以用您想要的類型替換T
。
using System;
using System.Collections;
using System.Collections.Generic;
namespace Demo
{
sealed class Node<T>
{
public T Data; // Payload.
public Node<T> Next; // This will point to the next sibling node (if any), forming a linked-list.
public Node<T> Child; // This will point to the first child node (if any).
}
sealed class Tree<T>: IEnumerable<T>
{
public Node<T> Root;
public Node<T> AddChild(Node<T> parent, T data)
{
parent.Child = new Node<T>
{
Data = data,
Next = parent.Child // Prepare to place the new node at the head of the linked-list of children.
};
return parent.Child;
}
public IEnumerator<T> GetEnumerator()
{
return enumerate(Root).GetEnumerator();
}
private IEnumerable<T> enumerate(Node<T> root)
{
for (var node = root; node != null; node = node.Next)
{
yield return node.Data;
foreach (var data in enumerate(node.Child))
yield return data;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
class Program
{
void run()
{
var tree = new Tree<string>();
tree.Root = new Node<string>{Data = "Root"};
var l1n3 = tree.AddChild(tree.Root, "L1 N3");
var l1n2 = tree.AddChild(tree.Root, "L1 N2");
var l1n1 = tree.AddChild(tree.Root, "L1 N1");
tree.AddChild(l1n1, "L2 N1 C3");
tree.AddChild(l1n1, "L2 N1 C2");
var l2n1 = tree.AddChild(l1n1, "L2 N1 C1");
tree.AddChild(l1n2, "L2 N2 C3");
tree.AddChild(l1n2, "L2 N2 C2");
tree.AddChild(l1n2, "L2 N2 C1");
tree.AddChild(l1n3, "L2 N3 C3");
tree.AddChild(l1n3, "L2 N3 C2");
tree.AddChild(l1n3, "L2 N3 C1");
tree.AddChild(l2n1, "L3 N1 C3");
tree.AddChild(l2n1, "L3 N1 C2");
tree.AddChild(l2n1, "L3 N1 C1");
tree.Print();
}
static void Main()
{
new Program().run();
}
}
static class DemoUtil
{
public static void Print(this object self)
{
Console.WriteLine(self);
}
public static void Print(this string self)
{
Console.WriteLine(self);
}
public static void Print<T>(this IEnumerable<T> self)
{
foreach (var item in self)
Console.WriteLine(item);
}
}
}
(我知道這是類似於Eric的回答以上,而如果我寫這一個我可能不會打擾你之前讀到的答案 - 但我已經寫了這一點,我沒有想要扔掉它。)
爲什麼不使用列表子代替Node子? –
Jerska
我無法使用任何Collections類。我只能用System來實現這個。 –
'我不能使用任何Collections類'爲什麼?這是一項家庭作業或面試任務嗎? –