跳至主要內容

701, 二叉搜索树中的插入操作

Mike大约 3 分钟binary treemediumbinary treebinary search tree

一、题目描述

给定二叉搜索树(BST)的根节点root和要插入树中的值value,将值插入二叉搜索树。返回插入后二叉搜索树的根节点。输入数据保证新值和原始二叉搜索树中的任意节点值都不同。

注意:可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。你可以返回任意有效的结果

示例 1

输入: root = [4, 2, 7, 1, 3], val = 5
输出: [4, 2, 7, 1, 3, 5]
解释: 另一个满足题目要求可以通过的树是:

示例 2
输入: root = [40, 20, 60, 10, 30, 50, 70], val = 25
输出: [40, 20, 60, 10, 30, 50, 70, null, null, 25]

示例 3
输入: root = [4, 2, 7, 1, 3, null, null, null, null, null, null], val = 5
输出: [4, 2, 7, 1, 3, 5]

提示

  • 树中的节点数将在[0, 10⁴]的范围内。
  • -10⁸ <= Node.val <= 10⁸
  • 所有值Node.val独一无二的。
  • -10⁸ <= val <= 10⁸
  • 保证val在原始BST中不存在。

相关主题

  • 二叉搜索树
  • 二叉树

二、题解

#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
    pub val: i32,
    pub left: Option<Rc<RefCell<TreeNode>>>,
    pub right: Option<Rc<RefCell<TreeNode>>>,
}

impl TreeNode {
    #[inline]
    pub fn new(val: i32) -> Self {
        TreeNode {
            val,
            left: None,
            right: None,
        }
    }
}

方法 1: 递归

pub fn insert_into_bst(root: Option<Rc<RefCell<TreeNode>>>, val: i32) -> Option<Rc<RefCell<TreeNode>>> {
    //Self::recur_helper_1(root, val
    Self::recur_helper_2(root, val)
}

fn recur_helper_1(root: Option<Rc<RefCell<TreeNode>>>, val: i32) -> Option<Rc<RefCell<TreeNode>>> {
    let new = Some(Rc::new(RefCell::new(TreeNode::new(val))));
    if root.is_none() {
        return new;
    }

    const TRAVERSAL: fn(Option<Rc<RefCell<TreeNode>>>, i32, Option<Rc<RefCell<TreeNode>>>) =
        |root, val, new| {
            if let Some(curr) = root {
                let curr_val = curr.borrow().val;

                if val > curr_val {
                    let right = curr.borrow().right.clone();
                    if right.is_some() {
                        TRAVERSAL(right, val, new);
                    } else {
                        curr.borrow_mut().right = new;
                    }
                } else {
                    let left = curr.borrow().left.clone();
                    if left.is_some() {
                        TRAVERSAL(left, val, new);
                    } else {
                        curr.borrow_mut().left = new;
                    }
                }
            }
        };
    TRAVERSAL(root.clone(), val, new);

    root
}

fn recur_helper_2(root: Option<Rc<RefCell<TreeNode>>>, val: i32) -> Option<Rc<RefCell<TreeNode>>> {
    const TRAVERSAL: fn(Option<Rc<RefCell<TreeNode>>>, i32) -> Option<Rc<RefCell<TreeNode>>> =
        |root, val| match root {
            None => Some(Rc::new(RefCell::new(TreeNode::new(val)))),
            Some(curr) => {
                let curr_val = curr.borrow().val;

                if val > curr_val {
                    let right = curr.borrow_mut().right.take();
                    curr.borrow_mut().right = TRAVERSAL(right, val);
                } else {
                    let left = curr.borrow_mut().left.take();
                    curr.borrow_mut().left = TRAVERSAL(left, val);
                }

                Some(curr)
            }
        };

    TRAVERSAL(root, val)
}

方法 2: 迭代

pub fn insert_into_bst(root: Option<Rc<RefCell<TreeNode>>>, val: i32) -> Option<Rc<RefCell<TreeNode>>> {
    //Self::iter_helper_1(root, val)
    Self::iter_helper_2(root, val)
}

fn iter_helper_1(root: Option<Rc<RefCell<TreeNode>>>, val: i32) -> Option<Rc<RefCell<TreeNode>>> {
    let new = Some(Rc::new(RefCell::new(TreeNode::new(val))));
    if root.is_none() {
        return new;
    }

    let mut root_node = root.clone();
    while let Some(curr) = root_node {
        let curr_val = curr.borrow().val;

        let (next, is_right) = if val > curr_val {
            (curr.borrow().right.clone(), true)
        } else {
            (curr.borrow().left.clone(), false)
        };

        if next.is_some() {
            root_node = next;
        } else {
            if is_right {
                curr.borrow_mut().right = new;
            } else {
                curr.borrow_mut().left = new;
            }
            break;
        }
    }

    root
}

fn iter_helper_2(root: Option<Rc<RefCell<TreeNode>>>, val: i32) -> Option<Rc<RefCell<TreeNode>>> {
    let new = Some(Rc::new(RefCell::new(TreeNode::new(val))));
    if root.is_none() {
        return new;
    }

    let mut root_node = root.clone();
    while let Some(curr) = root_node {
        let curr_val = curr.borrow().val;

        if val > curr_val {
            let right = curr.borrow().right.clone();
            if right.is_some() {
                root_node = right;
            } else {
                curr.borrow_mut().right = new;
                break;
            }
        } else {
            let left = curr.borrow().left.clone();
            if left.is_some() {
                root_node = left;
            } else {
                curr.borrow_mut().left = new;
                break;
            }
        }
    }

    root
}