From 06006c58a28468ff46022b841d7bf3ae53212846 Mon Sep 17 00:00:00 2001 From: Night Cruising <77157236+night-cruise@users.noreply.github.com> Date: Wed, 26 Jul 2023 09:15:58 +0800 Subject: [PATCH] feat: add rust codes for array binary tree (#654) * feat: add rust codes for array binary tree * update tree_node.rs * update: add implementation of vec_to_tree and tree_to_vec * update tree_node.rs * Update tree_node.rs --------- Co-authored-by: Yudong Jin --- codes/rust/Cargo.toml | 5 + codes/rust/chapter_tree/array_binary_tree.rs | 199 +++++++++++++++++++ codes/rust/include/tree_node.rs | 110 +++++----- 3 files changed, 255 insertions(+), 59 deletions(-) create mode 100644 codes/rust/chapter_tree/array_binary_tree.rs diff --git a/codes/rust/Cargo.toml b/codes/rust/Cargo.toml index cd528c925..12065cf83 100644 --- a/codes/rust/Cargo.toml +++ b/codes/rust/Cargo.toml @@ -154,6 +154,11 @@ path = "chapter_stack_and_queue/array_stack.rs" name = "array_queue" path = "chapter_stack_and_queue/array_queue.rs" +# Run Command: cargo run --bin array_binary_tree +[[bin]] +name = "array_binary_tree" +path = "chapter_tree/array_binary_tree.rs" + # Run Command: cargo run --bin avl_tree [[bin]] name = "avl_tree" diff --git a/codes/rust/chapter_tree/array_binary_tree.rs b/codes/rust/chapter_tree/array_binary_tree.rs new file mode 100644 index 000000000..d9c49309d --- /dev/null +++ b/codes/rust/chapter_tree/array_binary_tree.rs @@ -0,0 +1,199 @@ +/* + * File: array_binary_tree.rs + * Created Time: 2023-07-25 + * Author: night-cruise (2586447362@qq.com) + */ + +include!("../include/include.rs"); + +/* 数组表示下的二叉树类 */ +struct ArrayBinaryTree { + tree: Vec>, +} + +impl ArrayBinaryTree { + /* 构造方法 */ + fn new(arr: Vec>) -> Self { + Self { tree: arr } + } + + /* 节点数量 */ + fn size(&self) -> i32 { + self.tree.len() as i32 + } + + /* 获取索引为 i 节点的值 */ + fn val(&self, i: i32) -> Option { + // 若索引越界,则返回 None ,代表空位 + if i < 0 || i >= self.size() { + None + } else { + self.tree[i as usize] + } + } + + /* 获取索引为 i 节点的左子节点的索引 */ + fn left(&self, i: i32) -> i32 { + 2 * i + 1 + } + + /* 获取索引为 i 节点的右子节点的索引 */ + fn right(&self, i: i32) -> i32 { + 2 * i + 2 + } + + /* 获取索引为 i 节点的父节点的索引 */ + fn parent(&self, i: i32) -> i32 { + (i - 1) / 2 + } + + /* 层序遍历 */ + fn level_order(&self) -> Vec { + let mut res = vec![]; + // 直接遍历数组 + for i in 0..self.size() { + if let Some(val) = self.val(i) { + res.push(val) + } + } + res + } + + /* 深度优先遍历 */ + fn dfs(&self, i: i32, order: &str, res: &mut Vec) { + if self.val(i).is_none() { + return; + } + let val = self.val(i).unwrap(); + // 前序遍历 + if order == "pre" { + res.push(val); + } + self.dfs(self.left(i), order, res); + // 中序遍历 + if order == "in" { + res.push(val); + } + self.dfs(self.right(i), order, res); + // 后序遍历 + if order == "post" { + res.push(val); + } + } + + /* 前序遍历 */ + fn pre_order(&self) -> Vec { + let mut res = vec![]; + self.dfs(0, "pre", &mut res); + res + } + + /* 中序遍历 */ + fn in_order(&self) -> Vec { + let mut res = vec![]; + self.dfs(0, "in", &mut res); + res + } + + /* 后序遍历 */ + fn post_order(&self) -> Vec { + let mut res = vec![]; + self.dfs(0, "post", &mut res); + res + } +} + +/* Driver Code */ +fn main() { + // 初始化二叉树 + // 这里借助了一个从数组直接生成二叉树的函数 + let arr = vec![ + Some(1), + Some(2), + Some(3), + Some(4), + None, + Some(6), + Some(7), + Some(8), + Some(9), + None, + None, + Some(12), + None, + None, + Some(15), + ]; + + let root = tree_node::vec_to_tree(arr.clone()).unwrap(); + println!("\n初始化二叉树\n"); + println!("二叉树的数组表示:"); + println!( + "[{}]", + arr.iter() + .map(|&val| if let Some(val) = val { + format!("{val}") + } else { + "null".to_string() + }) + .collect::>() + .join(", ") + ); + println!("二叉树的链表表示:"); + print_util::print_tree(&root); + + // 数组表示下的二叉树类 + let abt = ArrayBinaryTree::new(arr); + + // 访问节点 + let i = 1; + let l = abt.left(i); + let r = abt.right(i); + let p = abt.parent(i); + println!( + "\n当前节点的索引为 {} ,值为 {}", + i, + if let Some(val) = abt.val(i) { + format!("{val}") + } else { + "null".to_string() + } + ); + println!( + "其左子节点的索引为 {} ,值为 {}", + l, + if let Some(val) = abt.val(l) { + format!("{val}") + } else { + "null".to_string() + } + ); + println!( + "其右子节点的索引为 {} ,值为 {}", + r, + if let Some(val) = abt.val(r) { + format!("{val}") + } else { + "null".to_string() + } + ); + println!( + "其父节点的索引为 {} ,值为 {}", + p, + if let Some(val) = abt.val(p) { + format!("{val}") + } else { + "null".to_string() + } + ); + + // 遍历树 + let mut res = abt.level_order(); + println!("\n层序遍历为:{:?}", res); + res = abt.pre_order(); + println!("前序遍历为:{:?}", res); + res = abt.in_order(); + println!("中序遍历为:{:?}", res); + res = abt.post_order(); + println!("后序遍历为:{:?}", res); +} \ No newline at end of file diff --git a/codes/rust/include/tree_node.rs b/codes/rust/include/tree_node.rs index 49bb9035e..779843343 100644 --- a/codes/rust/include/tree_node.rs +++ b/codes/rust/include/tree_node.rs @@ -1,14 +1,13 @@ -/** +/* * File: tree_node.rs * Created Time: 2023-02-27 - * Author: xBLACKICEx (xBLACKICE@outlook.com) + * Author: xBLACKICEx (xBLACKICE@outlook.com), night-cruise (2586447362@qq.com) */ use std::cell::RefCell; -use std::collections::VecDeque; use std::rc::Rc; -#[allow(dead_code)] +/* 二叉树节点类型 */ #[derive(Debug)] pub struct TreeNode { pub val: i32, @@ -19,6 +18,7 @@ pub struct TreeNode { } impl TreeNode { + /* 构造方法 */ pub fn new(val: i32) -> Rc> { Rc::new(RefCell::new(Self { val, @@ -39,63 +39,55 @@ macro_rules! op_vec { }; } -/// This function takes a vector of integers and generates a binary tree from it in a level order traversal manner. -/// The first element of the vector is used as the root node of the tree. Each node in the tree is represented by a `TreeNode` struct that has a value and pointers to its left and right children. -/// -/// # Arguments -/// -/// * `list` - A vector of integers to be used to generate the binary tree. -/// -/// # Returns -/// -/// An `Option>>` where the `Option` is `None` if the vector is empty, and `Some` containing the root node of the tree otherwise. -/// -/// # Examples -/// -/// ``` -/// use std::rc::Rc; -/// use std::cell::RefCell; -/// use std::collections::VecDeque; -/// -/// let list = vec![1, 2, 3, 4, 5, 6, 7]; -/// let root = vec_to_tree(list).unwrap(); -/// -/// // The resulting tree looks like: -/// // -/// // 1 -/// // / \ -/// // 2 3 -/// // / \ / \ -/// // 4 56 7 -/// ``` -pub fn vec_to_tree(list: Vec>) -> Option>> { - if list.is_empty() { +// 序列化编码规则请参考: +// https://www.hello-algo.com/chapter_tree/array_representation_of_tree/ +// 二叉树的数组表示: +// [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15] +// 二叉树的链表表示: +// /——— 15 +// /——— 7 +// /——— 3 +// | \——— 6 +// | \——— 12 +// ——— 1 +// \——— 2 +// | /——— 9 +// \——— 4 +// \——— 8 + +/* 将列表反序列化为二叉树:递归 */ +fn vec_to_tree_dfs(arr: &[Option], i: usize) -> Option>> { + if i >= arr.len() || arr[i].is_none() { return None; } + let root = TreeNode::new(arr[i].unwrap()); + root.borrow_mut().left = vec_to_tree_dfs(arr, 2 * i + 1); + root.borrow_mut().right = vec_to_tree_dfs(arr, 2 * i + 2); + Some(root) +} - let root = TreeNode::new(list[0].unwrap()); - let mut que = VecDeque::new(); - que.push_back(Rc::clone(&root)); - - let mut index = 0; - while let Some(node) = que.pop_front() { - index += 1; - if index >= list.len() { - break; - } - if let Some(val) = list[index] { - node.borrow_mut().left = Some(TreeNode::new(val)); - que.push_back(Rc::clone(&node.borrow().left.as_ref().unwrap())); - } +/* 将列表反序列化为二叉树 */ +pub fn vec_to_tree(arr: Vec>) -> Option>> { + vec_to_tree_dfs(&arr, 0) +} - index += 1; - if index >= list.len() { - break; - } - if let Some(val) = list[index] { - node.borrow_mut().right = Some(TreeNode::new(val)); - que.push_back(Rc::clone(&node.borrow().right.as_ref().unwrap())); - } +/* 将二叉树序列化为列表:递归 */ +fn tree_to_vec_dfs(root: Option>>, i: usize, res: &mut Vec>) { + if root.is_none() { + return; + } + let root = root.unwrap(); + while i >= res.len() { + res.push(None); } - Some(root) -} \ No newline at end of file + res[i] = Some(root.borrow().val); + tree_to_vec_dfs(root.borrow().left.clone(), 2 * i + 1, res); + tree_to_vec_dfs(root.borrow().right.clone(), 2 * i + 2, res); +} + +/* 将二叉树序列化为列表 */ +pub fn tree_to_vec(root: Option>>) -> Vec> { + let mut res = vec![]; + tree_to_vec_dfs(root, 0, &mut res); + res +}