2025-04-25 21:14:54 +09:00

130 lines
2.7 KiB
C#

using NUnit.Framework;
using System;
using System.Collections.Generic;
namespace GenericTree
{
/// <summary>
/// Generic tree interface
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
interface ITreeNode<T, U>
where T : ITreeNode<T, U>
{
bool IsValid { get; }
int ValueIndex { get; }
U Value { get; }
bool HasParent { get; }
T Parent { get; }
IEnumerable<T> Children { get; }
}
/// <summary>
/// Item has parent reference by list index
/// </summary>
public interface ITreeItem
{
int ParentIndex { get; }
}
/// <summary>
/// Generic tree implementation
/// </summary>
/// <typeparam name="T"></typeparam>
struct TreeNode<T> : ITreeNode<TreeNode<T>, T>
where T : ITreeItem
{
/// <summary>
/// Whole tree nodes
/// </summary>
public readonly List<T> Values;
public bool IsValid
{
get
{
return Values != null;
}
}
/// <summary>
/// This node index
/// </summary>
public int ValueIndex
{
get;
private set;
}
public T Value
{
get
{
if (Values == null)
{
return default(T);
}
return Values[ValueIndex];
}
}
public IEnumerable<TreeNode<T>> Children
{
get
{
for (int i = 0; i < Values.Count; ++i)
{
if (Values[i].ParentIndex == ValueIndex)
{
yield return new TreeNode<T>(Values, i);
}
}
}
}
public bool HasParent
{
get
{
return Value.ParentIndex >= 0 && Value.ParentIndex < Values.Count;
}
}
public TreeNode<T> Parent
{
get
{
if (Value.ParentIndex < 0)
{
throw new Exception("this may root node");
}
if (Value.ParentIndex >= Values.Count)
{
throw new IndexOutOfRangeException();
}
return new TreeNode<T>(Values, Value.ParentIndex);
}
}
public TreeNode(List<T> values, int index) : this()
{
Values = values;
ValueIndex = index;
}
}
class TreeTests
{
[Test]
public void TreeTest()
{
}
}
}