use std::rc::Rc;
use std::cell::RefCell;
#[derive(Debug, Clone)]
pub struct TreeNode {
pub val: i32,
pub left: Option<Rc<RefCell<TreeNode>>>,
pub right: Option<Rc<RefCell<TreeNode>>>,
}
impl TreeNode {
pub fn new(val: i32) -> Rc<RefCell<TreeNode>> {
Rc::new(RefCell::new(TreeNode { val, left: None, right: None }))
}
}
fn delete_node(root: Option<Rc<RefCell<TreeNode>>>, key: i32) -> Option<Rc<RefCell<TreeNode>>> {
if root.is_none() {
return None;
}
let root_rc = root.unwrap();
let mut root_ref = root_rc.borrow_mut();
if key < root_ref.val {
// go left
let left = root_ref.left.take();
root_ref.left = delete_node(left, key);
return Some(root_rc.clone());
} else if key > root_ref.val {
// go right
let right = root_ref.right.take();
root_ref.right = delete_node(right, key);
return Some(root_rc.clone());
} else {
// found node to delete
if root_ref.left.is_none() {
return root_ref.right.clone();
} else if root_ref.right.is_none() {
return root_ref.left.clone();
} else {
// two children: find inorder successor
let mut successor = root_ref.right.clone().unwrap();
while successor.borrow().left.is_some() {
let left = successor.borrow().left.clone().unwrap();
successor = left;
}
// replace value
root_ref.val = successor.borrow().val;
// delete successor node
let right = root_ref.right.take();
root_ref.right = delete_node(right, root_ref.val);
return Some(root_rc.clone());
}
}
}
fn print_bst(root: &Option<Rc<RefCell<TreeNode>>>) {
fn helper(node: &Option<Rc<RefCell<TreeNode>>>, prefix: String, is_left: bool) {
if let Some(n) = node {
println!("{}{}{}", prefix, if is_left {"├── "} else {"└── "}, n.borrow().val);
let new_prefix = prefix.clone() + if is_left {"│ "} else {" "};
helper(&n.borrow().left, new_prefix.clone(), true);
helper(&n.borrow().right, new_prefix, false);
}
}
helper(root, String::new(), false);
}
fn main() {
// Build tree: 5,3,7,2,4,8
let root = Some(TreeNode::new(5));
{
let r = root.as_ref().unwrap();
r.borrow_mut().left = Some(TreeNode::new(3));
r.borrow_mut().right = Some(TreeNode::new(7));
}
{
let left = root.as_ref().unwrap().borrow().left.clone().unwrap();
left.borrow_mut().left = Some(TreeNode::new(2));
left.borrow_mut().right = Some(TreeNode::new(4));
}
{
let right = root.as_ref().unwrap().borrow().right.clone().unwrap();
right.borrow_mut().right = Some(TreeNode::new(8));
}
println!("Original BST:");
print_bst(&root);
let root = delete_node(root, 3);
println!("\nBST after deleting 3:");
print_bst(&root);
}
if root.is_none() { return None; }
handle empty subtree base case
if key < root_ref.val { root_ref.left = delete_node(root_ref.left.take(), key); return Some(root_rc.clone()); }
recurse left if key smaller
else if key > root_ref.val { root_ref.right = delete_node(root_ref.right.take(), key); return Some(root_rc.clone()); }
recurse right if key larger
if root_ref.left.is_none() { return root_ref.right.clone(); } else if root_ref.right.is_none() { return root_ref.left.clone(); }
delete node with zero or one child by returning child
let mut successor = root_ref.right.clone().unwrap(); while successor.borrow().left.is_some() { successor = successor.borrow().left.clone().unwrap(); }
find inorder successor (smallest in right subtree)
root_ref.val = successor.borrow().val;
replace node value with successor value
root_ref.right = delete_node(root_ref.right.take(), root_ref.val);
delete successor node recursively
Original BST:
└── 5
├── 3
│ ├── 2
│ └── 4
└── 7
└── 8
BST after deleting 3:
└── 5
├── 4
│ ├── 2
└── 7
└── 8