当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Rust BTreeMap用法及代码示例


本文简要介绍rust语言中 Struct alloc::collections::btree_map::BTreeMap 的用法。

用法

pub struct BTreeMap<K, V> { /* fields omitted */ }

基于 B-Tree 的Map。

B-Trees 代表了缓存效率和实际最小化搜索中执行的工作量之间的基本折衷。理论上,二叉搜索树 (BST) 是排序图的最佳选择,因为完美平衡的 BST 执行查找元素所需的理论最小比较量 (log2n).然而,实际上这样做的方式是非常对于现代计算机体系结构来说效率低下。特别是,每个元素都存储在其自己的heap-allocated 节点中。这意味着每次插入都会触发heap-allocation,并且每次比较都应该是缓存未命中。由于这些在实践中都是非常昂贵的事情,我们被迫至少重新考虑 BST 策略。

相反,B-Tree 使每个节点在连续数组中包含 B-1 到 2B-1 个元素。通过这样做,我们将分配次数减少了 B 倍,并提高了搜索时的缓存效率。然而,这确实意味着搜索必须进行更多的平均比较。精确的比较次数取决于所使用的节点搜索策略。为了获得最佳缓存效率,可以线性搜索节点。为了获得最佳比较,可以使用二分搜索来搜索节点。作为一种折衷方案,我们还可以执行线性搜索,最初仅检查每个 ithi 的某些选择的元素。

目前,我们的实现只是简单地执行简单的线性搜索。这在比较便宜的元素的小节点上提供了出色的性能。然而,在未来,我们将进一步探索基于 B 的选择以及可能的其他因子来选择最优搜索策略。使用线性搜索,搜索随机元素预计需要 B * log(n) 比较,这通常比 BST 差。然而,在实践中,性能非常出色。

以这样的方式修改键是一个逻辑错误,即键相对于任何其他键的顺序(由 Ord 特征确定)在映射中时发生变化。这通常只能通过 Cell RefCell 、全局状态、I/O 或不安全代码实现。未指定由此类逻辑错误导致的行为(它可能包括Panics、不正确的结果、中止、内存泄漏或未终止),但不会是未定义的行为。

例子

use std::collections::BTreeMap;

// type inference lets us omit an explicit type signature (which
// would be `BTreeMap<&str, &str>` in this example).
let mut movie_reviews = BTreeMap::new();

// review some movies.
movie_reviews.insert("Office Space",       "Deals with real issues in the workplace.");
movie_reviews.insert("Pulp Fiction",       "Masterpiece.");
movie_reviews.insert("The Godfather",      "Very enjoyable.");
movie_reviews.insert("The Blues Brothers", "Eye lyked it a lot.");

// check for a specific one.
if !movie_reviews.contains_key("Les Misérables") {
    println!("We've got {} reviews, but Les Misérables ain't one.",
             movie_reviews.len());
}

// oops, this review has a lot of spelling mistakes, let's delete it.
movie_reviews.remove("The Blues Brothers");

// look up the values associated with some keys.
let to_find = ["Up!", "Office Space"];
for movie in &to_find {
    match movie_reviews.get(movie) {
       Some(review) => println!("{}: {}", movie, review),
       None => println!("{} is unreviewed.", movie)
    }
}

// Look up the value for a key (will panic if the key is not found).
println!("Movie review: {}", movie_reviews["Office Space"]);

// iterate over everything.
for (movie, review) in &movie_reviews {
    println!("{}: \"{}\"", movie, review);
}

可以从数组初始化具有已知项目列表的BTreeMap

use std::collections::BTreeMap;

let solar_distance = BTreeMap::from([
    ("Mercury", 0.4),
    ("Venus", 0.7),
    ("Earth", 1.0),
    ("Mars", 1.5),
]);

BTreeMap 实现了一个 Entry API ,它允许获取、设置、更新和删除键及其值的复杂方法:

use std::collections::BTreeMap;

// type inference lets us omit an explicit type signature (which
// would be `BTreeMap<&str, u8>` in this example).
let mut player_stats = BTreeMap::new();

fn random_stat_buff() -> u8 {
    // could actually return some random value here - let's just return
    // some fixed value for now
    42
}

// insert a key only if it doesn't already exist
player_stats.entry("health").or_insert(100);

// insert a key using a function that provides a new value only if it
// doesn't already exist
player_stats.entry("defence").or_insert_with(random_stat_buff);

// update a key, guarding against the key possibly not being set
let stat = player_stats.entry("attack").or_insert(100);
*stat += random_stat_buff();

相关用法


注:本文由纯净天空筛选整理自rust-lang.org大神的英文原创作品 Struct alloc::collections::btree_map::BTreeMap。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。