#node-tree #tree-structure #tree-node #tree #vec #data-structure

tree_by_path

一种树形数据结构,其节点可以通过一个Vec路径进行寻址,避免了递归和运行时借用检查。

4个稳定版本

1.0.3 2023年11月22日
1.0.0 2023年11月21日

#626数据结构


masterpg 中使用

MIT/Apache

110KB
1.5K SLoC

tree_by_path

作者:Koen Bekx

用法

为了使用此包,请使用以下命令将其添加到项目中的Cargo.toml文件:

cargo add tree_by_path

并在您的代码中添加以下语句

use tree_by_path::{Node, PathError, TraverseAction};

树是节点

pub struct Node<C> {
    pub cargo: C,
    pub children: Vec<Node<C>>,
}

tree_by_path树由一个Node根节点组成,该节点可能具有或不具有Node子节点,这些子节点再可能具有或不具有其他Node子节点等。

每个节点都携带一个通用的C类型有效载荷("货物")。(可以通过实例化一个具有Option节点树的树来获得有效载荷的可空性。)

子节点直接由父节点拥有,作为其子节点向量的元素:Vec>。

子节点不保留对父节点的引用。然而,可以通过从节点已寻址的索引数组中删除最后一个元素来始终检索父节点——见下文。

选择此设计是为了避免使用RefCell或其他内部可变性机制,这些机制将借用检查从编译时推迟到运行时。

寻址路径

除了根节点外,树中的所有节点都是其父节点子节点集合中的第n个元素。

这意味着每个节点都可以使用一系列索引的Vec来寻址

  • 根节点的地址是一个空索引序列:[];
  • 根节点下的任何直接子节点在其地址中都有一个索引,从 [0] 开始;
  • 其他节点有更长的地址,例如:
 []
  |
 [0]-----------------[1]-----------------[2]
  |                   |
 [0,0]---[0,1]       [1,0]---[1,1]
          |                   |
         [0,1,0]             [1,1,0]---[1,1,1]---[1,1,2]

这些地址即为crate名称所指的路径。

这些地址(由 &Vec<usize> 对象接受并返回的,几乎所有的 struct Node<C> 方法)的使用,允许使用此crate的代码仅保留对根节点的一个可变引用,而不需要其他引用,从而避免了由于Rust的借用检查器而禁止的保留同一树中多个节点可变引用的需要。

因此,除了节点的引用之外,还可以在变量中保留 Vec<usize> 路径的实例。

即使这些路径地址在插入或删除节点后可能变得过时,如果需要,也可以通过节点上的 traverse* 方法查找特定的节点 - 请参阅crate文档中的 节点标识符 部分。

循环父子节点所有权

尚未找到方法强制节点将其父节点之一作为其子向量中的子节点,这是更好的。

克隆

Node<C> 可克隆,如果类型 C 可克隆。

示例

有关使用示例,请参阅crate的文档或src/lib.rs中的单元测试。

无运行时依赖