【问题标题】: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) .

标签: c# .net data-structures


【解决方案1】:

不,BCL 中没有任何“Tree&lt;T&gt;-like”类型(这也一直让我感到困惑),但here is a good article 将引导您在 C# 中实现自己的类型。

我想您可能会认为基于树的数据结构在 .NET 通常用于的应用程序(商业应用程序、数据移动应用程序等)中不太常用。不过,我同意你的看法,奇怪的是 BCL 根本没有实现。

【讨论】:

    【解决方案2】:

    您可以使用TreeNode。它不是通用的并且隐藏在 Windows 窗体中并与树视图控件一起使用,但您也可以在其他地方使用它。

    【讨论】:

    • 是的,但它只有一个 System.Object ype 的 Tag 属性。没有通用 参数
    • 我总是觉得做这样的事情很奇怪。在您的特定示例中不太明显,但是如果人们经常从依赖项中重新使用类,这可能会导致难以解释的依赖关系,并且如果重新使用的类以意想不到的方式更改,可能会给您带来麻烦依赖版本。
    • 使用它有什么好处?树节点通常没有任何相关的功能。它只包含对孩子和最终父母的引用。没有理由滥用 System.Windows.Forms 类!只需自己编写 - 在一分钟或更短的时间内。
    【解决方案3】:

    我相信 SortedDictionary 作为 log(n) 插入,检索特征是您期望从树数据结构中获得的特征。

    http://msdn.microsoft.com/en-us/library/f7fta44c(VS.80).aspx

    【讨论】:

      【解决方案4】:

      SortedSet&lt;T&gt; 实现为二叉搜索树refSortedDictionary&lt;TKey, TValue&gt; 内部使用了SortedSet&lt;T&gt;,所以它也是一个二叉搜索树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吗?它超级好用,而且他们有几个树实现(123)。

        【讨论】:

        • C5 支持红黑树而不是 B-Tree。它们是人们应该意识到的差异。 B-Tree 更适合基于磁盘的树或基于大内存的树。更多节点保持在同一位置,因此您可以获得更好的处理器缓存性能并更快地读取写入磁盘。
        猜你喜欢
        • 1970-01-01
        • 2011-04-09
        • 2023-01-26
        • 2010-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-09
        • 2013-12-06
        相关资源
        最近更新 更多