This is a more or less stream of consciousness implementation of an immutable binary search tree. Trees are represented as empty or three-element lists:
(define (ibst-make . args) ; Return a bst. If there are no arguments, return an empty bst. If ; there is one argument, return a leaf bst having the argument as ; its value. If there are three arguments, return a bst with the ; first, second, and third arguments as the bst's value, left child, ; and right child respectively. If there are any other number of ; arguments, die with an error message. (let ((n (length args))) (cond ((zero? n) '()) ((= n 1) (ibst-makeo (car args) (ibst-make) (ibst-make))) ((= n 3) args) (#t (error "ibst-make argument count not 0, 1, or 3: " n))))) (define ibst-value car) (define ibst-left-child cadr) (define ibst-right-child caddr) (define ibst-empty? null?)
The tree-membership procedure looks as you'd expect.
(define (ibst-member? root v)
; Return #t iff the given bst contains the given value.
(if (ibst-empty? root)
#f
(let ((value (ibst-value root)))
(if (= v value)
#t
(ibst-member?
((if (< v value) ibst-left-child ibst-right-child) root) v)))))
Because the trees are immutable, the element-add and element-delete procedures may have an unexpected look: each returns a tree with the appropriate relation to the tree and element given as input to the associated procedure.
(define (ibst-add root v) ; Return a bst containing all the values in the given bst and one ; extra value equal to the given value. The returned bst can ; contain multiples of the same value. (if (ibst-empty? root) (ibst-make v) (let ((right (ibst-right-child root)) (left (ibst-left-child root)) (value (ibst-value root))) (if (< v value) (ibst-make value (ibst-add left v) right) (ibst-make value left (ibst-add right v)))))) (define (ibst-delete root v) ; Return a bst that contains one fewer nodes with the value v than ; does the bst root; if root doesn't contain v, the returned bst is ; a copy of root. (define (get-min root) ; Return a pair (v . t), where v is the smallest value in the ; non-empty bst root, and t is a bst containing all the values in ; root except for v. (let ((right (ibst-right-child root)) (left (ibst-left-child root)) (value (ibst-value root))) (if (ibst-empty? left) (cons value right) (let ((res (get-min left))) (cons (car res) (ibst-make value (cdr res) right)))))) (define (get-max root) ; Return a pair (v . t), where v is the largest value in the ; non-empty bst root, and t is a bst containing all the values in ; root except for v. (let ((right (ibst-right-child root)) (left (ibst-left-child root)) (value (ibst-value root))) (if (ibst-empty? right) (cons value left) (let ((res (get-max right))) (cons (car res) (ibst-make value left (cdr res))))))) (if (ibst-empty? root) root (let ((value (ibst-value root)) (left (ibst-left-child root)) (right (ibst-right-child root))) (cond ((= value v) (cond ((not (ibst-empty? left)) (let ((res (get-max left))) (ibst-make (car res) (cdr res) right))) ((not (ibst-empty? right)) (let ((res (get-min right))) (ibst-make (car res) left (cdr res)))) (#t (ibst-make)))) ((< value v) (ibst-make value left (ibst-delete right v))) (#t (ibst-make value (ibst-delete left v) right))))))
If you don't like trees implemented as lists, you can implement them as vectors.
(define (ibst-make . args) ; Return a bst. If there are no arguments, return an empty bst. If ; there is one argument, return a leaf bst having the argument as ; its value. If there are three arguments, return a bst with the ; first, second, and third arguments as the bst's value, left child, ; and right child respectively. If there are any other number of ; arguments, die with an error message. (let ((n (length args))) (cond ((zero? n) (make-vector 0)) ((= n 1) (ibst-make (car args) (ibst-make) (ibst-make))) ((= n 3) (list->vector args)) (#t (error "ibst-make argument count not 0, 1, or 3: " n))))) (define (ibst-value ibst) (vector-ref ibst 0)) (define (ibst-left-child ibst) (vector-ref ibst 1)) (define (ibst-right-child ibst) (vector-ref ibst 2)) (define (ibst-empty? ibst) (zero? (vector-length ibst)))