阅读BTreeSet
文档,我似乎无法弄清楚如何在对数时间内获得比BTreeSet
中的元素大的最小值或最大值。
我看到有一个range
方法可以在任意(最小,最大)范围内给出值,但如果我不知道范围并且我只想要前一个和/或对数时间的下一个元素?
这类似于C ++中lower_bound
中的upper_bound
和std::set
。
答案 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)