1 个不稳定版本
0.4.0 | 2023 年 4 月 8 日 |
---|
#1965 在 数据结构
在 2 crates 中使用
52KB
526 行
树
Rizzen Yazston
欢迎来到 Tree 项目。
一个简单的树结构,包含数据节点。The tree
crate 提供了 Tree
结构体,它可以存储实现 Any
特性的任何数据。提供了用于操作树结构和获取有关树结构和其节点信息的方法。通过一个方法 data_mut
操作节点数据,该方法简单地提供一个对包含数据的向量的可变引用。如果只需要读取,则 data_ref
方法是一个不可变引用。
在内部,树使用一个包含树中节点信息的节点结构体。信息包括:直接父节点、包含子节点的向量、节点的特征、节点类型、数据类型,以及包含数据的向量。除了节点的特征(决定节点在树中的行为)外,所有节点结构体字段都是可选的。
节点的特征在节点创建时指定,作为 insert
和 insert_at
方法参数 features
,通过传递所选特征的联合体。目前树支持两个特征
-
ALLOW_CHILDREN
:指示节点是否有子节点, -
ALLOW_DATA
:指示节点是否有数据。
在创建节点时,通过 node_type
和 data_type
参数传递以指定节点和数据类型。一旦设置,这些字段只读取一次。节点类型通常用于表示节点是什么,特别是在节点类型不能从节点数据中确定,或者节点没有任何数据(如结构信息)时。数据类型通常在整棵树的数据为不同类型时使用。数据类型通常指定以帮助正确地将数据下转换为其实际类型。由于节点可以支持多个数据实例,因此建议节点内的所有数据实例具有相同的类型,因为节点只有一个数据类型字段。尽管可以使用比简单的枚举更复杂的字符串来指示节点中使用的所有数据类型。
注意:一旦 core::error::Error
停止是实验性的,这个库将只依赖 core
,因此将适用于 no_std
环境。
仓库中只包含 tree
crate。
注意:在 crates.io
上的 crate 的名称后面附加了后缀 -rizzen-yazston
,以区分其他作者的 tree crate。
致谢
Stefano Angeleri,在实现节点树的各种设计方面的建议,并提供错误消息字符串的意大利语翻译。
用法
只需将 tree-rizzen-yazston
crate 包含在 Cargo.toml
中,使其可供应用程序或库使用。由于其简单的设计,创建空树时不需要进行配置。节点在将节点插入树时进行配置。
Cargo.toml
[dependencies]
tree-rizzen-yazston = "0.4.0"
示例
此示例使用 String
作为所有具有数据的节点的数据类型,因此参数 data_type
是 None
,表示它未使用。可以使用字符串 "String"
明确表示数据类型为 String
。或者,如果所有数据类型在编译时都是已知的,可以使用简单的枚举来表示数据类型。
由于数据是字符串,它们携带很少的结构信息(并非所有节点都包含数据),因此使用枚举来表示节点类型是一个很好的选择。与 data_type
一样,字符串也可以用于 node_type
。
use tree::{Tree, ALLOW_CHILDREN, ALLOW_DATA};
enum Nodes {
Root,
Statement,
Equal,
Divide,
Add,
Leaf,
}
let mut tree = Tree::new();
let no_data = ALLOW_CHILDREN;
let variable = ALLOW_DATA;
// Build tree of one statement: z = (x + y) / 2
// Just ignoring the `Result` using .ok() as this is a trivial example.
let mut index = tree.insert( 300, no_data.clone(), Some( Box::new( Nodes::Root ) ), None ).unwrap();
tree.insert( index, no_data.clone(), Some( Box::new( Nodes::Statement ) ), None ).ok();
tree.insert( 1, no_data.clone(), Some( Box::new( Nodes::Equal ) ), None ).ok();
index = tree.insert( 2, variable.clone(), Some( Box::new( Nodes::Leaf ) ), None ).unwrap();
tree.data_mut( index ).unwrap().push( Box::new( "z".to_string() ) );
tree.insert( 2, no_data.clone(), Some( Box::new( Nodes::Divide ) ), None ).ok();
tree.insert( 4, no_data.clone(), Some( Box::new( Nodes::Add ) ), None ).ok();
index = tree.insert( 5, variable.clone(), Some( Box::new( Nodes::Leaf ) ), None ).unwrap();
tree.data_mut( index ).unwrap().push( Box::new( "x".to_string() ) );
index = tree.insert( 5, variable.clone(), Some( Box::new( Nodes::Leaf ) ), None ).unwrap();
tree.data_mut( index ).unwrap().push( Box::new( "y".to_string() ) );
index = tree.insert( 4, variable.clone(), Some( Box::new( Nodes::Leaf ) ), None ).unwrap();
tree.data_mut( index ).unwrap().push( Box::new( "2".to_string() ) );
assert_eq!( tree.count(), 9, "9 nodes are present." );