如何获取BTreeSet中元素的下界和上界?

时间:2018-02-02 04:48:50

标签: rust

阅读BTreeSet文档,我似乎无法弄清楚如何在对数时间内获得比BTreeSet中的元素大的最小值或最大值。

我看到有一个range方法可以在任意(最小,最大)范围内给出值,但如果我不知道范围并且我只想要前一个和/或对数时间的下一个元素?

这类似于C ++中lower_bound中的upper_boundstd::set

3 个答案:

答案 0 :(得分:3)

  

但如果我不知道范围

怎么办?

然后使用无界范围:

use std::collections::BTreeSet;

fn neighbors(tree: &BTreeSet<i32>, val: i32) -> (Option<&i32>, Option<&i32>) {
    use std::ops::Bound::*;

    let mut before = tree.range((Unbounded, Excluded(val)));
    let mut after = tree.range((Excluded(val), Unbounded));

    (before.next_back(), after.next())
}

fn main() {
    let tree: BTreeSet<_> = [1, 3, 5].iter().cloned().collect();

    let (prev, next) = neighbors(&tree, 2);

    println!("greatest less than 2: {:?}", prev);
    println!("least bigger than 2:  {:?}", next);
}
greatest less than 2: Some(1)
least bigger than 2:  Some(3)

BTreeSet::range返回一个双端迭代器,因此你可以从它的两边拉。

请注意,我们使用的是非常明确的Bound运算符,因此我们不会包含我们正在查找的值。

一直在讨论如何增强BTreeMap / BTreeSet以获得“游标”API,这可能允许您找到一个元素,然后在树内“移动”。这将允许您避免在树中搜索两次找到起始节点,但它尚未实现。

A pull request was opened to do so,但它被关闭了,因为它被认为应该有更多关于这样的API应该如何看起来和工作的讨论。

答案 1 :(得分:2)

嗯......如果你不介意修改当前的收藏品并且性能受到影响......看来你可以创造性地使用split_off

let mut tree = BTreeSet::new();
tree.insert(1);
tree.insert(3);
tree.insert(5);

let other = tree.split_off(&2);

println!("{:?}", tree);
println!("{:?}", other);

将打印{1}{3, 5}

  • 下限是第二个范围的第一个元素,
  • 如果不相等,则上限是第二个范围的第一个元素,否则为第二个。

完成后,您可以使用tree.append(other)重组树。

是的,它真的不太理想......

答案 2 :(得分:2)

如果您可以更改数据结构,可以使用intrusive collections

您有所需的方法: