您可以使用仅具有下一个指针和子指针的节点类型来表示多路树。
该节点的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类'为什么?这是一项家庭作业或面试任务吗? –