------------------------------------------------------------------------------
MC logo
CSc 404 Assignment 2
[^] CSc 404 Home
------------------------------------------------------------------------------
[CSc 404 Assignment 1] [CSc 404 Assignment 2] [CSc 404 Assignment 3]
[Binary Tree Operations]

Assigned
Due
Jan 31
Feb 16
70 pts

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. 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(log n) comparisons in a 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, log n 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(log n) steps to find the maximum value.

(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.