;;; Example showing use of ``defabs'' construct:
;;;     Binary trees
;;; Rishiyur Nikhil, Aug 23, 1988

;;; ----------------------------------------------------------------
;;; A binary tree has one of two forms:

(defabs 'empty)
(defabs '(node val left right))

;;; ----------------------------------------------------------------
;;; Adding up all the numbers in a binary tree:

(define (count-tree t)
    (cond
      ((empty? t) 0)
      ((node?  t) (+ (node-val t)
                     (count-tree (node-left t))
                     (count-tree (node-right t))))
      (else       (error "count-tree: argument is not a tree"))))

;;; ----------------------------------------------------------------
;;; ``Reflecting'' a tree (left-right)

(define (reflect-tree t)
    (cond
      ((empty? t) t)
      ((node?  t) (node (node-val t)
                        (reflect-tree (node-right t))
                        (reflect-tree (node-left  t))))
      (else       (error "reflect-tree: argument is not a tree"))))

;;; ----------------------------------------------------------------
;;; Generating a ``full'' binary tree with depth D containing value V everywhere

(define (full-tree d v)
    (if (= d 0)
        empty
        (node v
              (full-tree (- d 1) v)
              (full-tree (- d 1) v))))

;;; ----------------------------------------------------------------
;;; Sorting a list using ordered binary trees:

;;; insert an element into an ordered tree

(define (insert x t)
    (cond
      ((empty? t) (node x empty empty))
      ((node?  t) (cond
                    ((< x (node-val t)) (node (node-val t)
                                              (insert x (node-left t))
                                              (node-right t)))
                    ((> x (node-val t)) (node (node-val t)
                                              (node-left t)
                                              (insert x (node-right t))))
                    (else               t)))))

;;; insert all elements from a list into an ordered tree

(define (insert-list-into-tree l t)
    (if (null? l)
        t
        (insert-list-into-tree (cdr l) (insert (car l) t))))

;;; list of elements in a tree, using in-order traversal

(define (inorder-into-list t l)
    (cond
      ((empty? t) l)
      ((node?  t) (inorder-into-list (node-left t)
                                     (cons (node-val t)
                                           (inorder-into-list (node-right t)
                                                              l))))))

;;; the top-level sort function

(define (sort l)
    (inorder-into-list (insert-list-into-tree l empty)
                       '()))

;;; ----------------------------------------------------------------
;;; Some test trees:

(define test-tree-1
    (node 100
          (node 50
                empty
                (node 75
                      (node 60
                            empty
                            empty)
                      (node 90
                            empty
                            empty)))
          (node 200
                (node 150
                      empty
                      empty)
                empty)))

(define test-tree-2
    (full-tree 5 23))
