The Mighty Forest
The lisp list structure is quite flexible, and can be used to
represent any number of things.
This file defines Tom's Lisp operations
to create and maintain binary search trees of integers
inside the list structure.
The representation is simple enough. Each node in the tree is a
list of three things: The data value at the node, the left subtree, and
the right subtree.
A tree is either empty, represented by nil, or not
empty, represented by a node list, including its subtrees.
For instance,
lsp>(load "bintree.lsp")
btree-delete
lsp>(btree-insert 5 (btree-insert 8 nil))
(8 (5 nil nil) nil)

This creates the very simple tree at the right. See that the
root is 8, its left child is leaf node 5, and the root has no
right child.
Of course, a complicated tree can be hard to read, but the tree operation
file also contains a printer which makes it a bit easier.
lsp>(btree-insert-all '(18 21 30 16 2 17 10 28) nil)
(18 (16 (2 nil (10 nil nil)) (17 nil nil)) (21 nil (30 (28 nil nil) nil)))
lsp>(btree-print (btree-insert-all '(18 21 30 16 2 17 10 28) nil))
30
28
21
18
17
16
10
2
nil
lsp>
The method btree-print outputs the structure in a way that's
at least more tree-like than the basic list representation. Think of it
as printing the tree rotated 90 degrees counter-clockwise so that the root
is on the left. The final nil in the printout is the value of the function.
(Printing is a side-effect.)
The BST file contains these primary functions:
(btree-insert item tree)
Takes an integer item and a tree tree, and returns a new version
of the tree with item added to it.
(btree-insert-all itemlist tree)
Takes a list of integers itemlist and
a tree tree, and returns a new version
of the tree with each member of items added to it, in order
left to right.
(btree-delete item tree)
Takes an integer item and a tree tree and returns a copy
of tree with item removed. If tree does not contain
item, an unchanged copy of tree is returned. If tree
contains multiple copies of item, the highest one is removed.
(btree-print tree)
Prints the tree tree and returns null.
lsp>(define a_tree (btree-insert-all '(14 20 18 10 4 22) nil)))
a_tree
lsp>(btree-print a_tree)
22
20
18
14
10
4
nil
lsp>(btree-print (btree-delete 20 a_tree))
22
18
14
10
4
nil
lsp>(btree-print a_tree)
22
20
18
14
10
4
nil
lsp>(btree-print (btree-delete 14 a_tree))
22
20
18
10
4
nil
lsp>(btree-print (btree-delete 7 a_tree))
22
20
18
14
10
4
nil
lsp>(btree-print (btree-delete 20 (btree-delete 4 (btree-delete 18 a_tree))))
22
14
10
nil
lsp>
Notice that operations which update the tree always return copies.
There is no notion of updating an existing tree in place; just making
a new one with changes.
This is the nature of Lisp
as a purely functional language.
For this assignment, create a file which can be loaded into Tom's Lisp
after loading bintree.lsp. You may assume all of its definitions
are available to you.
Do not copy the
code into your file; just load each file into tomslsp.
Do not try to change the bintree.lsp, just add new definitions
or redefinitions.
Implement the following functions:
(btree-contains item tree)
Takes an integer item and a BST tree and returns #t
if tree contains item, or nil otherwise. Use the
standard BST search
techniques to perform no more than O(logn) comparisons
in a balanced tree of n nodes.
(btree-count item tree)
Takes an integer item and a BST tree and returns
an integer count of the number of times
item occurs in tree. The existing insert method is
happy to place multiple copies in a tree, so this really is different
from the other method. As the previous, logn behavior is required.
(btree-list-in tree)
Return a plain Lisp list containing the items in BST tree arranged
in in-order (sorted order).
Hint: You will probably want to use the built-in append function
in the body of your btree-list-in.
(btree-max tree)
Return the maximum value in the tree. If the tree is empty, return nil.
Do not use more than O(logn) steps to find the maximum value,
assuming a balanced tree.
(btree-delete-max tree)
Return a copy of BST tree with its maximum element removed. If tree
is empty, return the empty tree. If the maximum element appears more than
once, any single copy may be removed.
lsp>(load "bintree.lsp")
btree-delete
lsp>(load "asst2.lsp")
btree-delete-max
lsp>(define a_tree (btree-insert-all '(18 21 30 18 16 2 17 10 28 21 2) nil))
a_tree
lsp>(btree-print a_tree)
30
28
21
21
18
18
17
16
10
2
2
nil
lsp>(btree-contains 28 a_tree)
#t
lsp>(btree-contains 9 a_tree)
nil
lsp>(btree-count 16 a_tree)
1
lsp>(btree-count 21 a_tree)
2
lsp>(btree-count 9 a_tree)
0
lsp>(btree-list-in a_tree)
(2 2 10 16 17 18 18 21 21 28 30)
lsp>(btree-list-in nil)
nil
lsp>(btree-max a_tree)
30
lsp>(btree-print (btree-delete-max a_tree))
28
21
21
18
18
17
16
10
2
2
nil
lsp>(btree-print (btree-delete-max (btree-delete-max (btree-delete-max a_tree))))
21
18
18
17
16
10
2
2
nil
lsp>
When your function works, is nicely formatted and documents,
submit it using
this
form.