具有泛型的树数据结构
本文关键字:数据结构 泛型 | 更新日期: 2023-09-27 18:00:52
我已经在桌子上敲了好几个小时了,但我似乎太愚蠢了,无法在C#中实现树结构。
- 有两种类型的节点,我称它们为
Node
和NodeCollection
Node
和NodeCollection
都可以有一个父NodeCollection
NodeCollection
可以具有子节点的集合,这些子节点是Node
或NodeCollection
Node
不能有任何子项- 没有父节点的
Node
或NodeCollection
被认为是根节点 -
Node
具有任意类型的值,使用泛型完成- NodeCollection
- NodeCollection
- 节点
- 节点
- NodeCollection
- 节点
- NodeCollection
- 节点
- 节点
- NodeCollection
- 节点
- NodeCollection
- NodeCollection
BCL中是否有用于此目的的集合类型?到目前为止我所拥有的:
public abstract class NodeBase {
protected NodeCollection Parent { get; set; }
}
public class Node<T> : NodeBase {
public string Key { get; set; }
public T Value { get; set; }
}
public class NodeCollection : NodeBase {
public ICollection<NodeBase> Children { get; set; }
}
这个解决方案"有效",但我不能只是走在树上,因为NodeBase
不提供任何childreen。我必须验证类型以确定子节点是否是NodeCollection
,但如果不是,我就无法正确地强制转换Node
,因为它可能是未知类型。
最简单的选择是只有一个Node
类(而不是有两种类型的节点,将叶子与非叶子节点分开(,并且让你的叶子节点只有一个空的子集合,而不是根本没有集合。
如果出于其他原因,拥有这两种类型的节点很重要,那么您希望它们都实现一个定义子节点集合的接口,叶节点将向其返回一个空集合。
为了处理没有到集合的链接的Node,我使用了一个名为"HasChildren"的抽象基类属性来允许检查,并确保如果您忘记检查并尝试访问子级,具体的Node实现会抛出异常。
public abstract class NodeBase<T> {
public abstract bool HasChildren { get; }
public abstract ICollection<T> Children { get; set; }
}
public class NodeCollection<T> : NodeBase<T> {
public override bool HasChildren { get { return true; } }
public override ICollection<T> Children { get; set; }
}
public class Node<T> : NodeBase<T> {
public override bool HasChildren { get { return false; } }
public override ICollection<T> Children { get { throw new Exception("blah"); } set { throw new Exception("blah"); } }
}
我使用抽象基类方法的Add
方法具体实现来确定要添加什么以及如何添加,对我来说,这还负责将项添加到NodeCollections的集合排序,并在需要时强制执行唯一性。