Java 如何使用二进制搜索从排序树集检索元素?

Java 如何使用二进制搜索从排序树集检索元素?,java,list,set,treeset,Java,List,Set,Treeset,我正在尝试将多个已排序的列表合并到一个树集中。。然后我考虑在树集上应用二进制搜索算法,以O(logn)的时间复杂度检索元素 下面是我的代码,我在其中一个方法中传递列表列表,并将它们组合到TreeSet中以避免重复。。。输入中的所有列表都已排序- private TreeSet<Integer> tree = new TreeSet<Integer>(); public void mergeMultipleLists(final List<List<Integ

我正在尝试将多个已排序的列表合并到一个树集中。。然后我考虑在树集上应用二进制搜索算法,以O(logn)的时间复杂度检索元素

下面是我的代码,我在其中一个方法中传递列表列表,并将它们组合到
TreeSet
中以避免重复。。。
输入中的所有列表都已排序-

private TreeSet<Integer> tree = new TreeSet<Integer>();

public void mergeMultipleLists(final List<List<Integer>> inputs) {
    tree = new TreeSet<Integer>();
    for (List<Integer> input : inputs) {
        for(Integer ii : input) {
            tree.add(ii);
        }
    }
}

public List<Integer> getItem(final Integer x) {
    // extract elements from TreeSet in O(log n)
}

TreeSet本质上是一个排序集,通过TreeMap使用红树和黑树作为支持

基本上:TreeSet.add(E)->TreeMap.put(E,NULL)

由于它已经是一个二进制的、已排序的树结构,任何“get”或“contains”都将导致一个O(logn)操作

你的代码和你的问题并不一致

您正在压平一个
列表
,并将它们全部放入其中以获得所有唯一的元素(或者,至少,这是此代码将要做的)

但是下面的方法说“给定这个整数,给我一个
列表”
,这在上面的代码中是无法实现的

因此,让我按顺序回答您的问题:

  • 当然可以
  • 不。如果你能做Set.contains(e),你就误解了Set(你不能通过设计提取) 那么您就有了元素,不需要提取任何内容

  • 如果您需要执行“集合提取”之类的操作,则使用树形图或将集合转换回列表,然后执行
    myList.get(Collections.binarySearch(myElement))

    TreeSet
    由一个
    NavigableMap
    ,一个
    TreeMap
    支持。在
    TreeSet
    上调用
    contains()
    将委托给
    TreeMap.containsKey()
    ,这是一个二进制搜索实现


    您可以使用
    TreeSet.contains()
    检查集合中是否包含对象,但必须先拥有该对象。如果您希望能够查找和检索对象,那么
    映射实现将更好。

    您可以使用TreeSet.floor(),它根据

    返回此集合中小于或等于给定元素的最大元素,如果没有此类元素,则返回null


    您可以使用
    TreeSet.addAll()
    而不是单独添加每个元素。这将节省一些LOC,但我不知道是否更有效。@MikeB:谢谢您提供的
    addAll
    提示。。我完全忘了。。现在关于我的第二个问题。。有什么想法吗?看起来这里的讨论是相关的:你说的“提取元素”是什么意思?是否要获取
    x
    th最大元素?是否要测试
    x
    是否位于
    TreeSet
    中?你想得到等于
    x
    的元素吗(在这种情况下…你只需要返回
    x
    ?)我想在
    TreeSet
    中找到一个
    x
    元素,如果它在那里,那么返回它,如果它不在那里,那么从
    TreeSet
    返回下一个最大的值。谢谢迈克。。我用最新的代码更新了这个问题。。早些时候我误解了,但在你的建议之后,几乎没有什么事情得到澄清。。但我的else声明中有一个疑问。。看一看我的代码..也许是
    树集
    中的
    higher()
    方法?我从来没用过,但它看起来像你想要的。作为将来的参考,您可以先查看javadocs,看看您的答案是否在那里:您确定它使用了binarysearch imp吗?看看TreeMap中的
    Entry getEntry
    ,对我来说,它看起来像是一个基于位置的“链接”搜索。自从我发布答案后,它可能已经改变了。不过,当时它确实是一个二进制搜索实现。
    public SearchItem(final List<List<Integer>> inputs) {
        tree = new TreeSet<Integer>();
        for (List<Integer> input : inputs) {
            tree.addAll(input);
        }
    }
    
    public Integer getItem(final Integer x) {
        if(tree.contains(x)) {
            return x;
        } else {
            // now how do I extract next largest 
             // element from it if x is not present
        }
    }