为啥 .NET 中没有 Tree<T> 类?
Posted
技术标签:
【中文标题】为啥 .NET 中没有 Tree<T> 类?【英文标题】:Why is there no Tree<T> class in .NET?为什么 .NET 中没有 Tree<T> 类? 【发布时间】:2010-10-30 20:01:18 【问题描述】:.NET 中的基类库具有一些出色的集合数据结构(列表、队列、堆栈、字典),但奇怪的是它不包含任何用于二叉树的数据结构。对于某些算法,例如那些利用不同遍历路径的算法,这是一个非常有用的结构。我正在寻找一个正确编写的免费实现。
我只是瞎了眼,没有找到它……它被埋在 BCL 的某个地方吗?如果没有,有人可以推荐一个用于二叉树的免费或开源 C#/.NET 库吗?最好是使用泛型的。
编辑:澄清我在寻找什么。我对内部使用树的有序字典集合不感兴趣。我实际上对二叉树感兴趣 - 一种公开其结构的二叉树,以便您可以执行诸如提取子树之类的操作,或在节点上执行修复后遍历。理想情况下,可以扩展这样的类以提供专门树的行为(即红/黑、AVL、平衡等)。
【问题讨论】:
同意。我偶尔需要找到(在 O(Log N) 时间内)绑定一个值的两个节点(当在集合中找不到该值时)。例如,集合(树)包含 13 和 17(以及其他),我正在寻找小于和最小大于 16 的最大值。树可以做到这一点,但字典、排序列表和哈希表需要 O(N) . 【参考方案1】:不,BCL 中没有任何“Tree<T>
-like”类型(这也一直让我感到困惑),但here is a good article 将引导您在 C# 中实现自己的类型。
我想您可能会认为基于树的数据结构在 .NET 通常用于的应用程序(商业应用程序、数据移动应用程序等)中不太常用。不过,我同意你的看法,奇怪的是 BCL 根本没有实现。
【讨论】:
【参考方案2】:您可以使用TreeNode。它不是通用的并且隐藏在 Windows 窗体中并与树视图控件一起使用,但您也可以在其他地方使用它。
【讨论】:
是的,但它只有一个 System.Object ype 的 Tag 属性。没有通用我相信 SortedDictionary
作为 log(n) 插入,检索特征是您期望从树数据结构中获得的特征。
http://msdn.microsoft.com/en-us/library/f7fta44c(VS.80).aspx
【讨论】:
【参考方案4】:SortedSet<T>
实现为二叉搜索树ref。 SortedDictionary<TKey, TValue>
内部使用了SortedSet<T>
,所以它也是一个二叉搜索树ref。
【讨论】:
不幸的是,这些只是有序映射和列表的简单实现。两者都不利于作为二叉树的重用——这些树结构只是集合的实现细节。我实际上正在寻找一个公开树结构的类。【参考方案5】:您希望从这样的实现中得到什么?
二叉树? 红黑? 萝卜树? B树? R树? R*-树?
树与其说是数据结构,不如说是一种模式,它们往往被用在性能很重要的地方(因此实现细节可能也很重要)。如果 BCL 包含某种树类,则无论如何您只需要滚动自己的类
【讨论】:
问题中“为什么”部分的最佳答案。 这些只是搜索树。还有表达式树、决策树…… 确实,实现细节很重要。就我而言,我希望实现一些算法,作为一系列转换的一部分,对有组织的数据集执行不同的遍历(中缀、后缀)。树结构是解决我的问题的最优雅的方式。 在平行宇宙中,有人问这个问题:“为什么 .Net 中没有列表类型?”,他们得到了答案:“你想从这样的实现中得到什么?一个数组?链表?队列?字典?”我认为这是一个不合逻辑的答案。【参考方案6】:你可以自己定义:
public class MyTree<K, V> : Dictionary<K, MyTree<K, V>>
public V Value get; set;
或无键:
public class MyTree<V> : HashSet<MyTree<V>>
public V Value get; set;
【讨论】:
这需要你知道在编译时你将处理多少个树级别,我错了吗? 不,C# 编译器支持这种语法。 注意元素是这样无序的 @Veverke 也许您在考虑 C++ 模板。 .NET 泛型是运行时类型。 使其成为继承自 System.Collections.Specialized.OrderedDictionary 的有序树【参考方案7】:当我不得不写自己的文章时,这一系列文章对我很有帮助,尤其是第 3 部分和第 4 部分。
An Extensive Examination of Data Structures
【讨论】:
【参考方案8】:你是对的,BCL 中没有任何内容。我怀疑这是因为选择是否使用树通常是实现细节,否则是访问数据的非常规方式。也就是说,您不会说“二分查找元素#37”;相反,你说,“给我找元素 #37”。
但是你看过C5吗?它超级好用,而且他们有几个树实现(1、2、3)。
【讨论】:
C5 支持红黑树而不是 B-Tree。它们是人们应该意识到的差异。 B-Tree 更适合基于磁盘的树或基于大内存的树。更多节点保持在同一位置,因此您可以获得更好的处理器缓存性能并更快地读取写入磁盘。以上是关于为啥 .NET 中没有 Tree<T> 类?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 ConcurrentBag<T> 在 .Net (4.0) 中这么慢?我做错了吗?
为啥 List<T> 在 .NET 4.5 中实现 IReadOnlyList<T>?
为啥 HashSet<T> 没有实现 ICollection?