Вы можете представить многоуровневое дерево, используя тип узла, который имеет только следующий указатель и дочерний указатель.
Указатель узла next
Указатель используется для указания на следующий дочерний дочерний элемент, реализованный в виде простого связанного списка.
Указатель узла child
Указатель используется для указания первого дочернего узла.
Вот пример кода, который демонстрирует, как это сделать. Он не содержит обработки ошибок и не предназначен для полного решения, но вы должны скомпилировать его и, при необходимости, запустить его под отладчиком, чтобы полностью понять, как он работает.
Я также добавил пример перечислимого, чтобы показать, как вы могли бы перебирать узлы дерева. Вы, вероятно, захотите поиграть с этим, чтобы получить результаты в разных заказах. ЕСЛИ использование перечислимого слишком сложно для того, что вам нужно, вам нужно будет написать свой собственный простой метод, чтобы посетить все узлы.
Обратите внимание, что тип узла является общим в этом примере, и я использую его только для хранения строковых данных. Вы можете просто заменить 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);
}
}
}
(я знаю, что это похоже на ответ Эрика выше, и если бы я прочитал, что ответ, прежде чем писать этот я, вероятно, не был бы потрудился, - но я уже написал это, и я не сделал хотите просто выбросить его.)
Почему бы не использовать список детей вместо узла ребенка? –
Jerska
Я не могу использовать любой из классов Collections. Я могу использовать System только для его реализации. –
'Я не могу использовать какой-либо класс Collections', почему? Это домашнее задание или интервью? –