Insert values into a binary search tree by comparing at each node.

Algorithm

The canonical tree is 4(2(1,3),6(5,7)), so this Go DSA implementation can be compared directly with the rest of the DSA track.

binary search tree Values smaller than a node go left; larger values go right.

Visual walkthrough

BST insertion is a comparison path. The pinned tree 4(2(1,3),6(5,7)) is shown with the inserted value taking its sorted slot.

Step 1 - Start at root

For value 5, compare with 4 first; 5 is larger, so move right.

First comparison: 5 > 4, so the search for the insert slot goes right.insert 54compare26137

Step 2 - Take the left slot under 6

At 6, value 5 is smaller, so it becomes the left child.

Second comparison: 5 < 6, so the open left slot is used.426compare135new7

Step 3 - Canonical tree

The resulting tree is the pinned shape 4(2(1,3),6(5,7)).

Final BST after 5 is present under 6.4261357

Basic Implementation

basic.go
package main

import (
    "fmt"
    "strings"
)

type Node struct { value int; left *Node; right *Node }
func render(node *Node) string {
    if node == nil { return "_" }
    if node.left == nil && node.right == nil { return fmt.Sprintf("%d", node.value) }
    return fmt.Sprintf("%d(%s,%s)", node.value, render(node.left), render(node.right))
}
func sampleTree() *Node {
    return &Node{4, &Node{2, &Node{1, nil, nil}, &Node{3, nil, nil}}, &Node{6, &Node{5, nil, nil}, &Node{7, nil, nil}}}
}
func listString(values []int) string {
    parts := []string{}
    for _, value := range values { parts = append(parts, fmt.Sprintf("%d", value)) }
    return "[" + strings.Join(parts, ", ") + "]"
}
func insert(root *Node, value int) *Node { if root == nil { return &Node{value: value} }; if value < root.value { root.left = insert(root.left, value) } else { root.right = insert(root.right, value) }; return root }
func main() { var root *Node; for _, value := range []int{4, 2, 6, 1, 3, 5, 7} { root = insert(root, value) }; fmt.Println(render(root)) }

Complexity

  • Time: O(h) per insert
  • Space: O(n)

Implementation notes

  • Go models each tree entry as type Node struct { value int; left *Node; right *Node }, so child links are nullable pointers.
  • insert(root *Node, value int) *Node is recursive. A nil root allocates a new node with &Node{value: value}; otherwise the function assigns the returned pointer into root.left or root.right.
  • main starts with var root *Node and reassigns root = insert(root, value) for each value in []int{4, 2, 6, 1, 3, 5, 7}, allowing the first insert to replace the nil root.
  • The branch uses value < root.value; equal values would follow the else path into the right subtree, though this replay has no duplicates.
  • The trace records paths and tree states after each insert: 4, 4(2,_), 4(2,6), 4(2(1,_),6), 4(2(1,3),6), 4(2(1,3),6(5,_)), then 4(2(1,3),6(5,7)).
  • render prints _ for nil children and value(left,right) for interior nodes; fmt.Println(render(root)) emits 4(2(1,3),6(5,7)).
  • The replay also includes a sorted-insert contrast, 1(_,2(_,3(_,4))), showing the Go pointer version still degrades without rotations.