#不可变 #持久化

fingertrees

不可变持久化手指树

15 个版本

0.2.11 2023年11月18日
0.2.10 2022年3月1日
0.2.9 2021年11月26日
0.2.4 2020年12月16日
0.2.1 2018年10月29日

#432 in 数据结构

42 次每月下载

MIT 许可证

61KB
1.5K SLoC

手指树

Build Status Coverage Status MIT License Crate API Docs

手指树是一种支持以摊销常数时间访问端点、以较小部分大小对数时间进行连接和拆分的持久序列的函数表示。它还定义了通用的 split 操作,可用于实现序列、优先队列、搜索树、优先搜索队列以及其他数据结构。

说明

  • 此实现不使用论文中描述的非正规递归类型,因为 Rust 的单态化与这种类型不兼容。
  • 实现通过类型家族技巧抽象了引用计数的类型 Rc/Arc
  • 实现使用严格的后背。
  • 迭代器返回克隆的值,通常此实现假设树中存储的值可以廉价地克隆,如果不能,你可以始终将其放入 Rc/Arc 或其他任何东西。

示例

use std::iter::FromIterator;
use fingertrees::measure::Size;
use fingertrees::monoid::Sum;
use fingertrees::{FingerTree, Measured, RcRefs};

// construct `Rc` based finger tree with `Size` measure
let ft: FingerTree<RcRefs, _> = vec!["one", "two", "three", "four", "five"]
    .into_iter()
    .map(Size)
    .collect();
assert_eq!(ft.measure(), Sum(5));

// split with predicate
let (left, right) = ft.split(|measure| *measure > Sum(2));
assert_eq!(left.measure(), Sum(2));
assert_eq!(Vec::from_iter(&left), vec![Size("one"), Size("two")]);
assert_eq!(right.measure(), Sum(3));
assert_eq!(Vec::from_iter(&right), vec![Size("three"), Size("four"), Size("five")]);

// concatenate
assert_eq!(ft, left + right);

// push values
assert_eq!(
    ft.push_left(Size("left")).push_right(Size("right")),
    vec!["left", "one", "two", "three", "four", "five", "right"]
         .into_iter()
         .map(Size)
         .collect(),
);

无运行时依赖