From b115a2b8952b48ff907c958ea7685f73855b2f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E6=98=A5=E9=A3=8E?= <77157236+night-cruise@users.noreply.github.com> Date: Sat, 23 Dec 2023 23:20:26 +0800 Subject: [PATCH] Fix the issue of discuss comment 7919887 (#996) --- codes/rust/chapter_tree/binary_search_tree.rs | 219 ++++++++---------- 1 file changed, 101 insertions(+), 118 deletions(-) diff --git a/codes/rust/chapter_tree/binary_search_tree.rs b/codes/rust/chapter_tree/binary_search_tree.rs index e6a1e7dd6..fa4498ad5 100644 --- a/codes/rust/chapter_tree/binary_search_tree.rs +++ b/codes/rust/chapter_tree/binary_search_tree.rs @@ -1,73 +1,51 @@ /* * File: binary_search_tree.rs * Created Time: 2023-04-20 - * Author: xBLACKICEx (xBLACKICE@outlook.com) + * Author: xBLACKICEx (xBLACKICE@outlook.com)、night-cruise (2586447362@qq.com) */ include!("../include/include.rs"); -use std::{cell::RefCell, rc::Rc}; +use std::cell::RefCell; +use std::rc::Rc; +use std::cmp::Ordering; + use tree_node::TreeNode; -type TreeNodeRc = Rc>; +type OptionTreeNodeRc = Option>>; /* 二叉搜索树 */ pub struct BinarySearchTree { - root: Option, + root: OptionTreeNodeRc, } impl BinarySearchTree { /* 构造方法 */ - pub fn new(mut nums: Vec) -> Self { - // 排序数组 - nums.sort(); - // 构建二叉搜索树 - if nums.is_empty() { - Self { root: None } - } else { - Self { root: Some(Self::build_tree(&nums)) } - } + pub fn new() -> Self { + // 初始化空树 + Self { root: None } } /* 获取二叉树根节点 */ - pub fn get_root(&self) -> Option { - self.root.clone() // RC 克隆 - } - - /* 构建二叉搜索树 */ - fn build_tree(num: &[i32]) -> TreeNodeRc { - // 将数组中间节点作为根节点 - let mid = num.len() / 2; - let root = TreeNode::new(num[mid]); - // 递归建立左子树和右子树 - if mid > 0 { - root.borrow_mut().left = Some(Self::build_tree(&num[..mid])); - } - if mid < num.len() - 1 { - root.borrow_mut().right = Some(Self::build_tree(&num[mid + 1..])); - } - root + pub fn get_root(&self) -> OptionTreeNodeRc { + self.root.clone() } /* 查找节点 */ - pub fn search(&self, num: i32) -> Option { + pub fn search(&self, num: i32) -> OptionTreeNodeRc { let mut cur = self.root.clone(); - // 循环查找,越过叶节点后跳出 while let Some(node) = cur.clone() { - // 目标节点在 cur 的右子树中 - if node.borrow().val < num { - cur = node.borrow().right.clone(); - } - // 目标节点在 cur 的左子树中 - else if node.borrow().val > num { - cur = node.borrow().left.clone(); - } - // 找到目标节点,跳出循环 - else { - break; + match num.cmp(&node.borrow().val) { + // 目标节点在 cur 的右子树中 + Ordering::Greater => cur = node.borrow().right.clone(), + // 目标节点在 cur 的左子树中 + Ordering::Less => cur = node.borrow().left.clone(), + // 找到目标节点,跳出循环 + Ordering::Equal => break, } } + // 返回目标节点 cur } @@ -83,27 +61,28 @@ impl BinarySearchTree { let mut pre = None; // 循环查找,越过叶节点后跳出 while let Some(node) = cur.clone() { - // 找到重复节点,直接返回 - if node.borrow().val == num { - return; - } - // 插入位置在 cur 的右子树中 - pre = cur.clone(); - if node.borrow().val < num { - cur = node.borrow().right.clone(); - } - // 插入位置在 cur 的左子树中 - else { - cur = node.borrow().left.clone(); + match num.cmp(&node.borrow().val) { + // 找到重复节点,直接返回 + Ordering::Equal => return, + // 插入位置在 cur 的右子树中 + Ordering::Greater => { + pre = cur.clone(); + cur = node.borrow().right.clone(); + } + // 插入位置在 cur 的左子树中 + Ordering::Less => { + pre = cur.clone(); + cur = node.borrow().left.clone(); + } } } // 插入节点 - let node = TreeNode::new(num); let pre = pre.unwrap(); - if pre.borrow().val < num { - pre.borrow_mut().right = Some(Rc::clone(&node)); + let node = Some(TreeNode::new(num)); + if num > pre.borrow().val { + pre.borrow_mut().right = node; } else { - pre.borrow_mut().left = Some(Rc::clone(&node)); + pre.borrow_mut().left = node; } } @@ -117,18 +96,19 @@ impl BinarySearchTree { let mut pre = None; // 循环查找,越过叶节点后跳出 while let Some(node) = cur.clone() { - // 找到待删除节点,跳出循环 - if node.borrow().val == num { - break; - } - // 待删除节点在 cur 的右子树中 - pre = cur.clone(); - if node.borrow().val < num { - cur = node.borrow().right.clone(); - } - // 待删除节点在 cur 的左子树中 - else { - cur = node.borrow().left.clone(); + match num.cmp(&node.borrow().val) { + // 找到待删除节点,跳出循环 + Ordering::Equal => break, + // 待删除节点在 cur 的右子树中 + Ordering::Greater => { + pre = cur.clone(); + cur = node.borrow().right.clone(); + } + // 待删除节点在 cur 的左子树中 + Ordering::Less => { + pre = cur.clone(); + cur = node.borrow().left.clone(); + } } } // 若无待删除节点,则直接返回 @@ -136,40 +116,43 @@ impl BinarySearchTree { return; } let cur = cur.unwrap(); - // 子节点数量 = 0 or 1 - if cur.borrow().left.is_none() || cur.borrow().right.is_none() { - // 当子节点数量 = 0 / 1 时, child = nullptr / 该子节点 - let child = cur.borrow().left.clone().or_else(|| cur.borrow().right.clone()); - let pre = pre.unwrap(); - let left = pre.borrow().left.clone().unwrap(); - // 删除节点 cur - if !Rc::ptr_eq(&cur, self.root.as_ref().unwrap()) { - if Rc::ptr_eq(&left, &cur) { - pre.borrow_mut().left = child; + let (left_child, right_child) = (cur.borrow().left.clone(), cur.borrow().right.clone()); + match (left_child.clone(), right_child.clone()) { + // 子节点数量 = 0 or 1 + (None, None) | (Some(_), None) | (None, Some(_)) => { + // 当子节点数量 = 0 / 1 时, child = nullptr / 该子节点 + let child = left_child.or(right_child); + let pre = pre.unwrap(); + // 删除节点 cur + if !Rc::ptr_eq(&cur, self.root.as_ref().unwrap()) { + let left = pre.borrow().left.clone(); + if left.is_some() && Rc::ptr_eq(&left.as_ref().unwrap(), &cur) { + pre.borrow_mut().left = child; + } else { + pre.borrow_mut().right = child; + } } else { - pre.borrow_mut().right = child; - } - } else { - // 若删除节点为根节点,则重新指定根节点 - self.root = child; - } - } - // 子节点数量 = 2 - else { - // 获取中序遍历中 cur 的下一个节点 - let mut tmp = cur.borrow().right.clone(); - while let Some(node) = tmp.clone() { - if node.borrow().left.is_some() { - tmp = node.borrow().left.clone(); - } else { - break; + // 若删除节点为根节点,则重新指定根节点 + self.root = child; } } - let tmpval = tmp.unwrap().borrow().val; - // 递归删除节点 tmp - self.remove(tmpval); - // 用 tmp 覆盖 cur - cur.borrow_mut().val = tmpval; + // 子节点数量 = 2 + (Some(_), Some(_)) => { + // 获取中序遍历中 cur 的下一个节点 + let mut tmp = cur.borrow().right.clone(); + while let Some(node) = tmp.clone() { + if node.borrow().left.is_some() { + tmp = node.borrow().left.clone(); + } else { + break; + } + } + let tmpval = tmp.unwrap().borrow().val; + // 递归删除节点 tmp + self.remove(tmpval); + // 用 tmp 覆盖 cur + cur.borrow_mut().val = tmpval; + } } } } @@ -177,32 +160,32 @@ impl BinarySearchTree { /* Driver Code */ fn main() { /* 初始化二叉搜索树 */ - let nums = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; - let mut bst = BinarySearchTree::new(nums); - println!("初始化的二叉树为\n"); - print_util::print_tree(&bst.get_root().unwrap()); + let mut bst = BinarySearchTree::new(); + // 请注意,不同的插入顺序会生成不同的二叉树,该序列可以生成一个完美二叉树 + let nums = [8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15]; + for &num in &nums { + bst.insert(num); + } + println!("\n初始化的二叉树为\n"); + print_util::print_tree(bst.get_root().as_ref().unwrap()); - /* 查找节点 */ - let node = bst.search(7).unwrap(); - println!( - "\n查找到的节点对象为: {:p} 节点值 = {}\n", - node.as_ref().as_ptr(), - node.borrow().val - ); + /* 查找结点 */ + let node = bst.search(7); + println!("\n查找到的节点对象为 {:?},节点值 = {}", node.clone().unwrap(), node.clone().unwrap().borrow().val); /* 插入节点 */ bst.insert(16); - println!("插入节点 16 后,二叉树为\n"); - print_util::print_tree(&bst.get_root().unwrap()); + println!("\n插入节点 16 后,二叉树为\n"); + print_util::print_tree(bst.get_root().as_ref().unwrap()); /* 删除节点 */ bst.remove(1); println!("\n删除节点 1 后,二叉树为\n"); - print_util::print_tree(&bst.get_root().unwrap()); + print_util::print_tree(bst.get_root().as_ref().unwrap()); bst.remove(2); println!("\n删除节点 2 后,二叉树为\n"); - print_util::print_tree(&bst.get_root().unwrap()); + print_util::print_tree(bst.get_root().as_ref().unwrap()); bst.remove(4); println!("\n删除节点 4 后,二叉树为\n"); - print_util::print_tree(&bst.get_root().unwrap()); + print_util::print_tree(bst.get_root().as_ref().unwrap()); }