Trees
BST Insert
Insert values into a binary search tree by comparing at each node.
Algorithm
Basic Implementation
basic.R
node <- function(value, left = NULL, right = NULL) list(value = value, left = left, right = right)
render <- function(n) {
if (is.null(n)) return("_")
if (is.null(n$left) && is.null(n$right)) return(as.character(n$value))
paste0(n$value, "(", render(n$left), ",", render(n$right), ")")
}
sample_tree <- function() node(4, node(2, node(1), node(3)), node(6, node(5), node(7)))
list_string <- function(values) paste0("[", paste(values, collapse = ", "), "]")
insert <- function(root, value) { if (is.null(root)) return(node(value)); if (value < root$value) root$left <- insert(root$left, value) else root$right <- insert(root$right, value); root }
root <- NULL
for (value in c(4, 2, 6, 1, 3, 5, 7)) root <- insert(root, value)
cat(render(root), "\n", sep = "")
Complexity
- Time: O(h) per insert
- Space: O(n)
Implementation notes
node <- function(value, left = NULL, right = NULL) list(...)builds each tree node as an R list withvalue,left, andrightfields.- The code reads and mutates those fields with
$, such asroot$value,root$left, androot$right. rootstarts asNULL. Wheninsert(root, value)sees aNULLroot, it returnsnode(value), so the loop must write the return value back withroot <- insert(root, value).- The pinned insertion order is
c(4, 2, 6, 1, 3, 5, 7). if (value < root$value)recurses left; theelsebranch recurses right. After assigningroot$leftorroot$right,insert()returnsroot.
Replay steps
4: root
2: 4 -> left
6: 4 -> right
1: 4 -> left -> 2 -> left
final: 4(2(1,3),6(5,7))
render()prints_forNULL, a bare character value for a leaf, andvalue(left,right)for an internal node.cat(render(root), "\n", sep = "")prints the canonical tree4(2(1,3),6(5,7)).- The trace keeps the imbalance contrast: sorted inserts
[1, 2, 3, 4]form1(_,2(_,3(_,4))), a height-4 chain with O(n) search/insert cost when no rotation step is present.
binary search tree
Values smaller than a node go left; larger values go right.