Trees
BST Insert
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
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) *Nodeis recursive. Anilroot allocates a new node with&Node{value: value}; otherwise the function assigns the returned pointer intoroot.leftorroot.right.mainstarts withvar root *Nodeand reassignsroot = 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 theelsepath 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,_)), then4(2(1,3),6(5,7)). renderprints_for nil children andvalue(left,right)for interior nodes;fmt.Println(render(root))emits4(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.