Rust蓝图树库re_blueprint_tree的使用:高效构建和管理复杂数据结构与层次关系
Rust蓝图树库re_blueprint_tree的使用:高效构建和管理复杂数据结构与层次关系
re_blueprint_tree是rerun系列crate的一部分,用于在左侧面板中实现蓝图树的UI界面。
安装
在项目目录中运行以下Cargo命令:
cargo add re_blueprint_tree
或者在Cargo.toml中添加:
re_blueprint_tree = "0.24.1"
许可证
该库采用MIT或Apache-2.0双许可证。
完整示例代码
以下是一个使用re_blueprint_tree构建和管理树形数据结构的完整示例:
use re_blueprint_tree::BlueprintTree;
use re_blueprint_tree::blueprint::Blueprint;
fn main() {
// 创建一个蓝图树实例
let mut blueprint_tree = BlueprintTree::new();
// 创建根节点
let root_node = Blueprint::new("Root".to_string());
let root_id = blueprint_tree.add_node(root_node, None);
// 添加子节点
let child1 = Blueprint::new("Child 1".to_string());
let child1_id = blueprint_tree.add_node(child1, Some(root_id));
let child2 = Blueprint::new("Child 2".to_string());
let child2_id = blueprint_tree.add_node(child2, Some(root_id));
// 为子节点添加孙子节点
let grandchild = Blueprint::new("Grandchild".to_string());
blueprint_tree.add_node(grandchild, Some(child1_id));
// 遍历树结构
println!("Tree structure:");
print_tree(&blueprint_tree, root_id, 0);
// 更新节点
if let Some(node) = blueprint_tree.get_node_mut(child2_id) {
node.set_name("Updated Child 2".to_string());
}
// 删除节点
blueprint_tree.remove_node(child2_id);
}
fn print_tree(tree: &BlueprintTree, node_id: usize, indent: usize) {
if let Some(node) = tree.get_node(node_id) {
println!("{:indent$}- {}", "", node.name(), indent = indent * 2);
for child_id in tree.get_children(node_id) {
print_tree(tree, child_id, indent + 1);
}
}
}
功能说明
- 创建树形结构:通过
add_node
方法可以添加节点,并指定父节点 - 节点管理:可以获取、更新和删除节点
- 层次关系:自动维护父子关系
- 树遍历:可以递归遍历整个树结构
完整示例demo
基于上述示例,这里提供一个更完整的演示,展示如何在实际应用中使用re_blueprint_tree:
use re_blueprint_tree::BlueprintTree;
use re_blueprint_tree::blueprint::Blueprint;
fn main() {
// 初始化蓝图树
let mut tree = BlueprintTree::new();
// 创建文件系统结构的树
let root = Blueprint::new("Root Directory".to_string());
let root_id = tree.add_node(root, None);
// 添加子目录
let documents = Blueprint::new("Documents".to_string());
let documents_id = tree.add_node(documents, Some(root_id));
let pictures = Blueprint::new("Pictures".to_string());
let pictures_id = tree.add_node(pictures, Some(root_id));
let downloads = Blueprint::new("Downloads".to_string());
let downloads_id = tree.add_node(downloads, Some(root_id));
// 在Documents下添加文件
let file1 = Blueprint::new("report.docx".to_string());
tree.add_node(file1, Some(documents_id));
let file2 = Blueprint::new("budget.xlsx".to_string());
tree.add_node(file2, Some(documents_id));
// 在Pictures下添加子目录和文件
let vacation = Blueprint::new("Vacation".to_string());
let vacation_id = tree.add_node(vacation, Some(pictures_id));
let photo1 = Blueprint::new("beach.jpg".to_string());
tree.add_node(photo1, Some(vacation_id));
let photo2 = Blueprint::new("mountain.jpg".to_string());
tree.add_node(photo2, Some(vacation_id));
// 打印树结构
println!("File System Structure:");
print_tree_with_metadata(&tree, root_id, 0);
// 重命名节点
if let Some(node) = tree.get_node_mut(downloads_id) {
node.set_name("My Downloads".to_string());
}
// 删除节点及其所有子节点
tree.remove_node(pictures_id);
}
// 增强版的打印函数,显示更多节点信息
fn print_tree_with_metadata(tree: &BlueprintTree, node_id: usize, indent: usize) {
if let Some(node) = tree.get_node(node_id) {
// 打印节点名称和缩进
println!("{:indent$}📁 {}", "", node.name(), indent = indent * 2);
// 获取并打印所有子节点
let children = tree.get_children(node_id);
for child_id in children {
if let Some(child) = tree.get_node(child_id) {
// 可以根据节点类型显示不同的图标
if child.name().ends_with(".jpg") || child.name().ends_with(".png") {
println!("{:indent$}🖼️ {}", "", child.name(), indent = (indent + 1) * 2);
} else if child.name().ends_with(".docx") || child.name().ends_with(".xlsx") {
println!("{:indent$}📄 {}", "", child.name(), indent = (indent + 1) * 2);
} else {
print_tree_with_metadata(tree, child_id, indent + 1);
}
}
}
}
}
这个增强版示例展示了:
- 更复杂的树形结构构建
- 节点类型的可视化区分
- 更详细的树结构打印功能
- 实际应用场景(文件系统)的模拟
1 回复
Rust蓝图树库re_blueprint_tree的使用指南
简介
re_blueprint_tree是一个用于高效构建和管理复杂数据结构与层次关系的Rust库。它特别适合需要处理树形结构数据的场景,如UI组件树、游戏对象层次结构、文档对象模型等。
主要特性
- 高效的内存布局和访问模式
- 类型安全的节点操作
- 支持层次结构的快速遍历和修改
- 提供多种遍历策略(深度优先、广度优先等)
- 线程安全设计(在合理使用的情况下)
基本使用方法
添加依赖
首先在Cargo.toml中添加依赖:
[dependencies]
re_blueprint_tree = "0.1" # 请使用最新版本号
创建树结构
use re_blueprint_tree::prelude::*;
// 定义节点数据
#[derive(Debug)]
struct TreeNode {
name: String,
value: i32,
}
fn main() {
// 创建树构建器
let mut builder = TreeBuilder::new();
// 添加根节点
let root = builder.add_node(TreeNode {
name: "Root".to_string(),
value: 0,
});
// 添加子节点
let child1 = builder.add_child(root, TreeNode {
name: "Child1".to_string(),
value: 1,
});
let child2 = builder.add_child(root, TreeNode {
name极客时间"Child2".to_string(),
value: 2,
});
// 添加孙子节点
builder.add_child(child1, TreeNode {
name: "Grandchild1".to_string(),
value: 11,
});
// 构建树
let tree = builder.build();
println!("Tree structure: {:?}", tree);
}
遍历树
// 深度优先遍历
fn print_tree_dfs(tree: &Tree<TreeNode>, node: NodeId, indent: usize) {
let node_data = tree.get(node).unwrap();
println!("{:indent$}{}: {}", "", node_data.name, node_data.value, indent=indent*2);
for child in tree.children(node) {
print_tree_dfs(tree, child, indent + 1);
}
}
// 在main函数中使用
print_tree_dfs(&tree, root, 0);
修改树结构
// 添加新节点到现有树中
let mut editor = tree.edit();
let new_child = editor.add_child(child2, TreeNode {
name: "NewChild".to_string(),
value: 3,
});
let updated_tree = editor.commit();
// 更新节点值
let mut editor = updated_tree.edit();
if let Some(mut node) = editor.get_mut(root) {
node.value = 100;
}
let final_tree = editor.commit();
高级用法
自定义遍历策略
use re_blueprint_tree::traversal::Traversal;
// 广度优先遍历
fn print_tree_bfs(tree: &Tree<TreeNode>, root: NodeId) {
let traversal = Traversal::BreadthFirst(root);
for node_id in traversal.iter(tree) {
let node = tree.get(node_id).unwrap();
println!("{}: {}", node.name, node.value);
}
}
并行处理树节点
use rayon::prelude::*;
fn process_tree_parallel(tree: &Tree<TreeNode>) {
tree.par_iter().for_each(|(_, node)| {
println!("Processing {} on thread {:?}", node.name, std::thread::current().id());
// 这里可以进行并行处理
});
}
性能提示
- 批量操作时使用
TreeEditor
进行多次修改后一次性提交 - 对于只读操作,尽量使用不可变引用
- 考虑使用
Tree::with_capacity
预分配空间以减少内存分配次数
错误处理
match tree.get(invalid_node_id) {
Some(node) => println!("Found node: {}", node.name),
None => println!("Node not found"),
}
完整示例代码
use re_blueprint_tree::prelude::*;
use rayon::prelude::*;
// 定义树节点数据结构
#[derive(Debug, Clone)]
struct TreeNode {
name: String,
value: i32,
}
fn main() {
// 1. 创建树结构
let mut builder = TreeBuilder::new();
// 添加根节点
let root = builder.add_node(TreeNode {
name: "Root".to_string(),
value: 0,
});
// 添加子节点
let child1 = builder.add_child(root, TreeNode {
name: "Child1".to_string(),
value: 1,
});
let child2 = builder.add_child(root, TreeNode {
name: "Child2".to_string(),
value: 2,
});
// 添加孙子节点
builder.add_child(child1, TreeNode {
name: "Grandchild1".to_string(),
value: 11,
});
// 构建树
let tree = builder.build();
// 2. 遍历树 - 深度优先
println!("深度优先遍历结果:");
print_tree_dfs(&tree, root, 0);
// 3. 修改树结构
let mut editor = tree.edit();
let new_child = editor.add_child(child2, TreeNode {
name: "NewChild".to_string(),
value: 3,
});
let updated_tree = editor.commit();
// 4. 广度优先遍历
println!("\n广度优先遍历结果:");
print_tree_bfs(&updated_tree, root);
// 5. 并行处理
println!("\n并行处理节点:");
process_tree_parallel(&updated_tree);
// 6. 错误处理示例
println!("\n错误处理示例:");
match updated_tree.get(NodeId::from(999)) { // 不存在的节点ID
Some(node) => println!("找到节点: {}", node.name),
None => println!("节点不存在"),
}
}
// 深度优先遍历
fn print_tree_dfs(tree: &Tree<TreeNode>, node: NodeId, indent: usize) {
let node_data = tree.get(node).unwrap();
println!("{:indent$}{}: {}", "", node_data.name, node_data.value, indent=indent*2);
for child in tree.children(node) {
print_tree_dfs(tree, child, indent + 1);
}
}
// 广度优先遍历
fn print_tree_bfs(tree: &Tree<TreeNode>, root: NodeId) {
let traversal = Traversal::BreadthFirst(root);
for node_id in traversal.iter(tree) {
let node = tree.get(node_id).unwrap();
println!("{}: {}", node.name, node.value);
}
}
// 并行处理树节点
fn process_tree_parallel(tree: &Tree<TreeNode>) {
tree.par_iter().for_each(|(id, node)| {
println!("处理节点 {} (ID: {}) 在线程 {:?}",
node.name, id, std::thread::current().id());
});
}
这个完整示例演示了re_blueprint_tree库的主要功能:
- 创建树结构
- 深度优先和广度优先遍历
- 修改树结构
- 并行处理节点
- 错误处理
输出结果会显示树的遍历顺序、并行处理时的线程分配情况以及错误处理示例。