【问题标题】:Tree construction from an ordered list从有序列表构建树
【发布时间】:2009-02-23 03:57:11
【问题描述】:

在 java 中,我从一个总是要排序的列表中创建一个 SortedSet(但只有 ArrayList 类型)。我认为一一添加它们的性能会很差(以 AVL 树为例),因为它必须对树进行大量重新排序。

我的问题是,我应该如何创建这个集合?以某种方式尽可能快地构建平衡树?

我计划使用的具体实现是来自http://fastutil.dsi.unimi.it/docs/it/unimi/dsi/fastutil/ints/IntSortedSet.html 的 IntRBTreeSet 或 IntAVLTreeSet

写完这篇文章后,我认为糟糕的性能无论如何不会对我造成太大影响(数据量太少),但我仍然对在一般情况下如何完成它感兴趣。

【问题讨论】:

    标签: java performance tree


    【解决方案1】:

    具有树实现的集合会将列表中的中间元素放在顶部。所以算法如下:

    1. 找到列表的中间元素
    2. 将其插入集合中
    3. 对中间元素左侧和右侧的两个子列表重复

    【讨论】:

    • 我认为这是一个不错的选择。仍然可以快速访问(数组)列表以插入它们,列表元素以这种方式排序的几率是多少(不是很高)。
    【解决方案2】:

    红黑树对于一般情况来说是一个不错的选择,它们的插入速度非常快。请参阅Chris Okasaki's paper 以获得优雅而快速的实现。 Functional Java 库有一个通用的 Set 类,它由根据本文实现的红黑树支持。

    【讨论】:

      【解决方案3】:

      在所有关于使用 Set 的讨论中,我突然想到这个问题可能会被重新陈述。为什么要使用 Set 呢?如果您只想检查成员资格,并且您的源列表已排序,那么对该对象进行二进制搜索 - 这将比您可以想象的任何 n-tree 一样快(并且可能更快),而且并不难代码。

      因此,设想一个仅包装底层 List 对象的 OrderedListSet 接口。只要用于排序列表的比较器也用于二分搜索,这应该很简单。

      所有 Set 操作都将从 getIndex(Object ob) 调用开始,然后对 List 采取适当的操作。

      【讨论】:

      • 问题是列表已排序,但它不在保证顺序的数据结构中。所以我可以假设它是有序的,但不能绝对确定我的代码会工作
      • 对我来说很有意义。我绝对建议您查看 GlazedLists - 它完全改变了我编写涉及列表的代码的方式。
      【解决方案4】:

      在元素到来时插入元素的简单方法是否存在性能问题?

      如果不是,不要优化。

      【讨论】:

      • 有效点。但为了便于讨论,我们假设他确实有性能问题。
      【解决方案5】:

      内置的 TreeSet (http://java.sun.com/j2se/1.4.2/docs/api/java/util/TreeSet.html) 类使用红黑树作为它的支持树(并且,已经注意到,红黑树对于插入非常快)。这是红黑树上的good info(在插入大部分已经排序的数据时,它们没有典型的二叉树实现的问题)。

      如果您正在处理庞大的数据集(大到需要基于磁盘的备份,或重要的分页文件交换),那么 B+Tree 是一个非常好的选择(请参阅 JDBM 了解基于 Java 的 self-平衡 B+Tree - 它没有实现 Set,但可以根据需要以这种方式使用)。

      根据您的应用程序实际使用这些数据的方式,您可能需要考虑使用GlazedLists 库并使您的列表“生效”。如果您所做的只是静态分析,那么这可能有点矫枉过正,但它绝对是处理基于列表的数据的绝佳方式。绝对值得一读。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多