

Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
A lab exercise from a computer science course on programming languages (cis 352 o) at a university. The lab focuses on practicing with lists and implementing abstract data types, specifically binary trees, in scheme. It covers the definition of binary trees, traversals (preorder, inorder, postorder), and provides exercises for the students to write scheme procedures. The document also includes hints and examples.
Typology: Lab Reports
1 / 2
This page cannot be seen from the preview
Don't miss anything!


This lab has two main purposes:
(1) to give you a bit more practice working with lists in Scheme, and (2) to illustrate one method for implementing abstract data types in Scheme.
You’ll need to remember a little about trees from Data-structures (CIS 351). If you have trouble with the terminology, check with a labmate or the TA or me.
The lab is pretty straightforward; so overly complex answers indicate something is likely amiss.
A binary tree is a tree where every node has either no children, a left child, a right child, or both a left and right child. Under this definition, the empty tree (i.e., the tree with no nodes) is also a binary tree. If we as- sume that every node has a numeric id, then binary trees can be specified by the following BNF specification:
〈bin-tree〉 ::= () | (〈number〉 〈bin-tree〉 〈bin-tree〉) (1)
For example, (5 (2 () (4 () ())) (7 (6 () ()) (15 () ()))) is a valid 〈bin-tree〉 (convince yourself before continuing), corresponding to the (abstract) tree that we might sketch as follows:
5 n
2 n^7 n
4 n^6 n^15 n
^
ZZ Z ee %% ee
Note that the role of () in 〈bin-tree〉 is similar to that of NULL pointers in Java, indicating the absence of any nodes at all. Therefore, a leaf is a 〈bin-tree〉 with form (〈number〉 () ()).
For any nonempty 〈bin-tree〉, we can extract its left child using cadr and its right child using caddr. It’s good to introduce mnemonic names for these procedures:
(define left-child cadr) (define right-child caddr)
These new names make it easier to think of each 〈bin-tree〉 as an abstract data structure rather than as a list and it is a lot easier to remember what right-child is supposed to do as opposed to caddr. Similarly, we can introduce new names for the procedures that indicate whether a 〈bin-tree〉 is empty and what a nonempty node’s id (i.e., number) is:
(define empty? null?) (define id car)
To play with these definitions a bit (and to minimize the pain of typing in sample trees), introduce the following definition (it’s the tree illustrated earlier):
(define tree1 ’(5 (2 () (4 () ())) (7 (6 () ()) (15 () ())) ))
Now evaluate the following expressions, and make sure you understand how they work:
(right-child tree1) (left-child (right-child tree1)) (id tree1) (empty? (left-child tree1)) (empty? (left-child (left-child tree1)))
A traversal is a scheme for visiting each node of a tree exactly once in a particular order—typically so that some type of operation can be done at each node. For example, if we want to create a list of the node ids for some purpose, we need to decide on the order in which to list the node ids. There are three standard (left-to-right) traversal schemes: preorder, inorder, and postorder.
In a preorder traversal , a node’s id is listed, followed by a preorder traversal of its left child and then a preorder traversal of its right child. For example, the preorder traversal of tree1 can be represented as the list (5 2 4 7 6 15). The Scheme code for creating this traversal list follows:
(define preorder (lambda (tree) (if (empty? tree) ’() (append (list (id tree)) (preorder (left-child tree)) (preorder (right-child tree))))))
In an inorder traversal , the traversal of a node’s left child occurs before that node’s id is listed; the traversal of the node’s right child still occurs last. Thus the inorder traversal of tree1 gives (2 4 5 6 7 15).
Finally, in a postorder traversal , a node’s id is listed (you guessed it!) after the traversals of its left and right children (in that order). The postorder traversal of tree1 yields (4 2 6 15 7 5).
(bin-tree? ’()) #t (bin-tree? 5) #f (bin-tree? ’(5 (2 () (4 () ())) (7 () ()))) #t (bin-tree? ’(5 (2 () (4 () ())) )) #f (bin-tree? ’(a () ())) #f
Hint: Consider equation (1).
Its id value is greater than that of every node of its left child and less than every node of its right child. (That is, every node that occurs to the left of it has a smaller id; every node that occurs to the right of it has a larger id.)
Write a Scheme procedure bst? that takes a binary tree tree and returns #t if tree is a binary search tree and #f otherwise. Hint: What’s special about an inorder traversal of a binary search tree?
What to Hand In Hand in your source code (including contracts and pur- poses for each procedure you’re asked to write), along with verified test cases that demonstrate that the code works as required. You do not have to submit anything electronically for this lab.