From 9c2e5e2831519dbff909332a58aa8c699b2299ee Mon Sep 17 00:00:00 2001 From: xBLACKICEx Date: Fri, 21 Apr 2023 08:58:46 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(rust/tree):=20add=20binary=5Ft?= =?UTF-8?q?ree=5Fbfs,=20binary=5Ftree=5Fdfs,=20=20(#450)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ feat(rust/tree): add binary_tree_dfs * ✨ feat(rust/tree): add binary_tree_bfs * 🐞 fix(rust/tree): can't list to any kind of tree --- codes/rust/Cargo.toml | 10 +++ codes/rust/chapter_tree/binary_tree_bfs.rs | 42 +++++++++++++ codes/rust/chapter_tree/binary_tree_dfs.rs | 70 +++++++++++++++++++++ codes/rust/include/tree_node.rs | 71 ++++++++++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 codes/rust/chapter_tree/binary_tree_bfs.rs create mode 100644 codes/rust/chapter_tree/binary_tree_dfs.rs diff --git a/codes/rust/Cargo.toml b/codes/rust/Cargo.toml index 65c77ed8..0f4fd58a 100644 --- a/codes/rust/Cargo.toml +++ b/codes/rust/Cargo.toml @@ -124,6 +124,16 @@ path = "chapter_stack_and_queue/array_stack.rs" name = "array_queue" path = "chapter_stack_and_queue/array_queue.rs" +# Run Command: cargo run --bin binary_tree_bfs +[[bin]] +name = "binary_tree_bfs" +path = "chapter_tree/binary_tree_bfs.rs" + +# Run Command: cargo run --bin binary_tree_dfs +[[bin]] +name = "binary_tree_dfs" +path = "chapter_tree/binary_tree_dfs.rs" + # Run Command: cargo run --bin binary_tree [[bin]] name = "binary_tree" diff --git a/codes/rust/chapter_tree/binary_tree_bfs.rs b/codes/rust/chapter_tree/binary_tree_bfs.rs new file mode 100644 index 00000000..816ca73e --- /dev/null +++ b/codes/rust/chapter_tree/binary_tree_bfs.rs @@ -0,0 +1,42 @@ +/** + * File: binary_tree_bfs.rs + * Created Time: 2023-04-07 + * Author: xBLACKICEx (xBLACKICE@outlook.com) + */ + +use std::collections::VecDeque; +use std::{cell::RefCell, rc::Rc}; +use tree_node::{vec_to_tree, TreeNode}; +include!("../include/include.rs"); + +fn level_order(root: &Rc>) -> Vec { + // 初始化队列,加入根结点 + let mut que = VecDeque::new(); + que.push_back(Rc::clone(&root)); + // 初始化一个列表,用于保存遍历序列 + let mut vec = Vec::new(); + + while let Some(node) = que.pop_front() { // 队列出队 + vec.push(node.borrow().val); // 保存结点值 + if let Some(left) = node.borrow().left.as_ref() { + que.push_back(Rc::clone(left)); // 左子结点入队 + } + if let Some(right) = node.borrow().right.as_ref() { + que.push_back(Rc::clone(right)); // 右子结点入队 + }; + } + vec +} + +/* Driver Code */ +fn main() { + /* 初始化二叉树 */ + // 这里借助了一个从数组直接生成二叉树的函数 + let root = vec_to_tree(op_vec![1, 2, 3, 4, 5, 6, 7]).unwrap(); + println!("初始化二叉树\n"); + print_util::print_tree(&root); + + /* 层序遍历 */ + let vec = level_order(&root); + print!("\n层序遍历的结点打印序列 = {:?}", vec); +} \ No newline at end of file diff --git a/codes/rust/chapter_tree/binary_tree_dfs.rs b/codes/rust/chapter_tree/binary_tree_dfs.rs new file mode 100644 index 00000000..59387d55 --- /dev/null +++ b/codes/rust/chapter_tree/binary_tree_dfs.rs @@ -0,0 +1,70 @@ +/** + * File: binary_tree_dfs.rs + * Created Time: 2023-04-06 + * Author: xBLACKICEx (xBLACKICE@outlook.com) + */ + +use std::cell::RefCell; +use std::rc::Rc; +use tree_node::{vec_to_tree, TreeNode}; +include!("../include/include.rs"); + +/* 前序遍历 */ +fn pre_order(root: Option<&Rc>>) -> Vec { + let mut result = vec![]; + + if let Some(node) = root { + // 访问优先级:根结点 -> 左子树 -> 右子树 + result.push(node.borrow().val); + result.append(&mut pre_order(node.borrow().left.as_ref())); + result.append(&mut pre_order(node.borrow().right.as_ref())); + } + result +} + +/* 中序遍历 */ +fn in_order(root: Option<&Rc>>) -> Vec { + let mut result = vec![]; + + if let Some(node) = root { + // 访问优先级:左子树 -> 根结点 -> 右子树 + result.append(&mut in_order(node.borrow().left.as_ref())); + result.push(node.borrow().val); + result.append(&mut in_order(node.borrow().right.as_ref())); + } + result +} + +/* 后序遍历 */ +fn post_order(root: Option<&Rc>>) -> Vec { + let mut result = vec![]; + + if let Some(node) = root { + // 访问优先级:左子树 -> 右子树 -> 根结点 + result.append(&mut post_order(node.borrow().left.as_ref())); + result.append(&mut post_order(node.borrow().right.as_ref())); + result.push(node.borrow().val); + } + result +} + +/* Driver Code */ +fn main() { + /* 初始化二叉树 */ + // 这里借助了一个从数组直接生成二叉树的函数 + let root = vec_to_tree(op_vec![1, 2, 3, 4, 5, 6, 7]); + println!("初始化二叉树\n"); + print_util::print_tree(root.as_ref().unwrap()); + + /* 前序遍历 */ + let vec = pre_order(root.as_ref()); + println!("\n前序遍历的结点打印序列 = {:?}", vec); + + /* 中序遍历 */ + let vec = in_order(root.as_ref()); + println!("\n中序遍历的结点打印序列 = {:?}", vec); + + /* 后序遍历 */ + let vec = post_order(root.as_ref()); + print!("\n后序遍历的结点打印序列 = {:?}", vec); +} \ No newline at end of file diff --git a/codes/rust/include/tree_node.rs b/codes/rust/include/tree_node.rs index b26d9809..8dae042e 100644 --- a/codes/rust/include/tree_node.rs +++ b/codes/rust/include/tree_node.rs @@ -5,6 +5,7 @@ */ use std::cell::RefCell; +use std::collections::VecDeque; use std::rc::Rc; #[allow(dead_code)] @@ -26,4 +27,74 @@ impl TreeNode { right: None })) } +} + +#[macro_export] +macro_rules! op_vec { + ( $( $x:expr ),* ) => { + vec![ + $( Option::from($x).map(|x| x) ),* + ] + }; +} + +/// 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() { + return None; + } + + 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())); + } + + 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())); + } + } + Some(root) } \ No newline at end of file