如何使用二进制搜索从已排序的TreeSet中检索元素?

时间:2014-02-27 19:24:07

标签: java list set treeset

我正在尝试将多个排序列表合并到一个TreeSet中。然后我想在该TreeSet上应用二进制搜索算法来检索O(log n)时间复杂度中的元素。

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

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中的正确方法吗?有没有直接的方法可以有效地合并TreeSet中的多个排序列表?
  • 其次,如何在O(log n)时间复杂度中从该TreeSet中提取元素?我想在x中找到一个元素TreeSet,如果它在那里,然后返回它,如果它不存在则返回TreeSet中的下一个最大值。

或者与我目前使用的数据结构相比,我可能会更好地使用其他数据结构吗?

更新后的代码: -

private TreeSet tree = new TreeSet();

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
    }
}

3 个答案:

答案 0 :(得分:3)

TreeSetNavigableMapTreeMap专门支持。在contains()代表上调用TreeSetTreeMap.containsKey(),这是一个二元搜索实现。

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

TreeSet,它本质上是一个排序集并通过TreeMap使用 red-tree-black-tree 作为它的支持

基本上:TreeSet.add(E) - &gt; TreeMap.put(E,NULL);

由于它已经是一个二进制的排序树结构,任何'get'或'contains'都会导致O(log n)操作。

您的代码和您的问题虽然没有对齐。

你正在展平List<List<Integer>>并将它们全部放入以获取所有独特元素(或者,至少,这就是这段代码的作用)。

但是接下来的方法是“给定这个整数,给我一个List<Integer>”,这在上面的代码中无法实现

所以,让我按顺序回答你的问题:

  1. 当然/是Y
  2. 否。你误会集(你不能通过设计提取)如果你可以做Set.contains(e) 然后你有元素,不需要提取任何东西
  3. 如果您需要执行类似“设置提取”的操作,请使用TreeMap或将您的设置转回列表并执行myList.get(Collections.binarySearch(myElement));