Insert into a binary search tree

LeetCode problem 701. Insert into a Binary Search Tree.

## Problem description

You are given the `root` node of a binary search tree (BST) and a `value` to insert into the tree. Return *the root node of the BST after the insertion*. It is **guaranteed** that the new value does not exist in the original BST.

**Notice** that there may exist multiple valid ways for the insertion, as long as the tree remains a BST after insertion. You can return **any of them**.

Example 1

* **Input**: root = [4,2,7,1,3], val = 5
* **Output**: [4,2,7,1,3,5]
* **Explanation**: Another accepted tree is:

Example 2
* **Input**: root = [40,20,60,10,30,50,70], val = 25
* **Output**: [40,20,60,10,30,50,70,null,null,25]

Example 3
* **Input**: root = [4,2,7,1,3,null,null,null,null,null,null], val = 5
* **Output**: [4,2,7,1,3,5]

Constraints
* The number of nodes in the tree will be in the range `[0, 104]`.
* `-108 <= Node.val <= 108`
* All the values `Node.val` are **unique**.
* `-108 <= val <= 108`
* It's **guaranteed** that `val` does not exist in the original BST.

## Analysis

We can create a pointer `curr` that starts from `root` of the binary tree. We use the following method to travel down from the root and find the spot of inserting the new node:

1. Check if we should step into the *left subtree*, i.e. if `curr.left != null` and `curr.val > val`. If yes, then `curr = curr.left`. Perform the next check.
2. Otherwise, check if we should step into the *right subtree*, i.e. if `right.left != null` and `curr.val < val`. If yes, then `curr = curr.right`. Perform the next check.
3. Otherwise, if we neither should get into the left subtree or the right subtree, this is the moment when we should insert the new node.
	* If `curr.val == val` then we do not insert anything.
	* If `curr.val > val` then we insert at the *left child*.
	* If `curr.val < val` then we insert at the *right child*.

### Complexity analysis

#### Time complexity

In the worst case the complexity is **O(n)**, when the binary search tree is *not necessarily balanced*.

For example: If we have a binary tree such that all child nodes are to the right of its parent, and we have to reach the bottom (e.g. given the tree 1 → 2 → 3 → 4 → 5 (same as a linked list), and we want to insert 6), then we have to traverse all the nodes.

#### Space complexity

Stack

Iterative approach
We only used a fix set of helper variables, `curr`, `left` (left child), and `right` (right child). So the space complexity on stack is O(1).
Recursive approach
A tail recursion can be used by passing down the root into each recursion level, so that each recursion level can return the root. As a result, we can make each recursion as the last step of the previous level of recursion. This brings space complexity down to O(1).
Heap
Except for the new node to allocate on heap, we do not need to allocate anything else. So the total space complexity on heap is O(1).
So the total space complexity is **O(1)**.

## Solution

### Iterative solution

#### C++

```
/\*\*
 \* Definition for a binary tree node.
 \* struct TreeNode {
 \* int val;
 \* TreeNode \*left;
 \* TreeNode \*right;
 \* TreeNode() : val(0), left(nullptr), right(nullptr) {}
 \* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 \* TreeNode(int x, TreeNode \*left, TreeNode \*right) : val(x), left(left), right(right) {}
 \* };
 \*/
class Solution {
public:
 TreeNode\* insertIntoBST(TreeNode\* root, const int& val) {
 // iterative approach

 // trivial case
 if (root == nullptr) {
 root = new TreeNode(val);
 return root;
 }

 // search from top to bottom
 TreeNode \*curr = root;
 while (curr->val != val) {
 TreeNode \*left = curr->left, \*right = curr->right;

 // check if we should go into left subtree
 if ((left != nullptr) && (curr->val > val)) {
 curr = left;
 }
 // check if we should go into right subtree
 else if ((right != nullptr) && (curr->val < val)) {
 curr = right;
 }
 // otherwise we have reached the node to insert new node
 // or if curr->val == val then we will immediately exit the while loop
 else {
 if (curr->val > val) {
 // insert at the left child
 curr->left = new TreeNode(val);
 }
 else {
 // insert at the right child
 curr->right = new TreeNode(val);
 }
 }
 }

 return root;
 }
};

```

#### Java

```
/\*\*
 \* Definition for a binary tree node.
 \* public class TreeNode {
 \* int val;
 \* TreeNode left;
 \* TreeNode right;
 \* TreeNode() {}
 \* TreeNode(int val) { this.val = val; }
 \* TreeNode(int val, TreeNode left, TreeNode right) {
 \* this.val = val;
 \* this.left = left;
 \* this.right = right;
 \* }
 \* }
 \*/
class Solution {
 public TreeNode insertIntoBST(TreeNode root, int val) {
 // iterative approach

 // trivial case
 if (root == null) {
 root = new TreeNode(val);
 return root;
 }

 // search from top to bottom
 TreeNode curr = root;
 while (curr.val != val) {
 TreeNode left = curr.left, right = curr.right;

 // check if we should go into left subtree
 if ((left != null) && (curr.val > val)) {
 curr = left;
 }
 // check if we should go into right subtree
 else if ((right != null) && (curr.val < val)) {
 curr = right;
 }
 // otherwise we have reached the node to insert new node
 // or if curr.val == val then we will immediately exit the while loop
 else {
 if (curr.val > val) {
 // insert at the left child
 curr.left = new TreeNode(val);
 }
 else {
 // insert at the right child
 curr.right = new TreeNode(val);
 }
 }
 }

 return root;
 }
}

```

### Recursive solution

Note
The two examples below use tail recursion.
#### C++

```
/\*\*
 \* Definition for a binary tree node.
 \* struct TreeNode {
 \* int val;
 \* TreeNode \*left;
 \* TreeNode \*right;
 \* TreeNode() : val(0), left(nullptr), right(nullptr) {}
 \* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 \* TreeNode(int x, TreeNode \*left, TreeNode \*right) : val(x), left(left), right(right) {}
 \* };
 \*/
class Solution {
private:
 static TreeNode\* insertIntoBST(TreeNode\* const root, TreeNode\* subRoot, const int& val) {
 // base case, no more insert
 if (subRoot->val == val) {
 return root;
 }

 TreeNode \*const left = subRoot->left, \*const right = subRoot->right;

 // check if we should insert in the left subtree
 if ((left != nullptr) && (subRoot->val > val)) {
 return insertIntoBST(root, left, val);
 }
 // check if we should insert in the right subtree
 else if ((right != nullptr) && (subRoot->val < val)) {
 return insertIntoBST(root, right, val);
 }
 // otherwise we have reached the place to insert
 else {
 // insert at left child
 if (subRoot->val > val) {
 subRoot->left = new TreeNode(val);
 return root;
 }
 // insert at right child
 else {
 subRoot->right = new TreeNode(val);
 return root;
 }
 }
 }

public:
 TreeNode\* insertIntoBST(TreeNode\* root, const int& val) {
 // recursive approach

 // trivial case
 if (root == nullptr) {
 root = new TreeNode(val);
 return root;
 }

 // search from top to bottom, and insert
 // use recursion
 return insertIntoBST(root, root, val);
 }
};

```

#### Java

```
/\*\*
 \* Definition for a binary tree node.
 \* public class TreeNode {
 \* int val;
 \* TreeNode left;
 \* TreeNode right;
 \* TreeNode() {}
 \* TreeNode(int val) { this.val = val; }
 \* TreeNode(int val, TreeNode left, TreeNode right) {
 \* this.val = val;
 \* this.left = left;
 \* this.right = right;
 \* }
 \* }
 \*/
class Solution {

 private static TreeNode insertIntoBST(TreeNode root, TreeNode subRoot, int val) {
 // base case, no more insert
 if (subRoot.val == val) {
 return root;
 }

 final TreeNode left = subRoot.left, right = subRoot.right;

 // check if we should insert in the left subtree
 if ((left != null) && (subRoot.val > val)) {
 return insertIntoBST(root, left, val);
 }
 // check if we should insert in the right subtree
 else if ((right != null) && (subRoot.val < val)) {
 return insertIntoBST(root, right, val);
 }
 // otherwise we have reached the place to insert
 else {
 // insert at left child
 if (subRoot.val > val) {
 subRoot.left = new TreeNode(val);
 return root;
 }
 // insert at right child
 else {
 subRoot.right = new TreeNode(val);
 return root;
 }
 }
 }

 public TreeNode insertIntoBST(TreeNode root, int val) {
 // recursive approach

 // trivial case
 if (root == null) {
 root = new TreeNode(val);
 return root;
 }

 // search from top to bottom, and insert
 // use recursion
 return insertIntoBST(root, root, val);
 }
}

```

## See also

* Search in a binary search tree
* Delete node in a binary search tree