CSI 2165, Winter 2006
Assignment 4
Due Mon, April 3, 11am
Submission instructions: The submission is done electronically through Virtual Campus.
Please submit a file called a4.pl with comments inside. The first comment should include your name and student number. The file should contain the Prolog code for the required predicates, and comments explaining what they do and how they do it. Add in comments example queries that you ran for testing each predicate and what the Prolog output was (thorough testing is important). Make sure your program can be loaded (consulted) in Prolog without giving errors. Make sure the name of the file and the names of the predicates are the required ones.
Note: No late assignments are allowed.
This assignment explores data structures, in
particular binary trees and binary search trees.
Binary trees can be represented as structures with
three arguments, lets say:
bt(Key, LeftSubTree,
RightSubTree).
The leaves of the trees can be denoted by:
bt(key, nil, nil)
where nil is just a constant to
represent an empty tree.
A binary search tree is a
binary tree such that the value of the key in a node is larger than the keys in
the left subtree and smaller than the keys in the
right subtree. For example the following binary search
tree:
4
/ \
2 5
/ \
1 3
is represented as:
bt(4, bt(2,
bt(1, nil, nil), bt(3, nil,
nil)), bt(5, nil, nil))
a. Implement a predicate that builds a binary search
tree from a list of numbers. The first element in the list is the root of the
tree, and all the elements of the list are inserted in the binary search tree
in the right positions, according to their values. The first element of the
list is inserted in an empty tree, the second element is inserted in the
previous tree, than the third element, etc. (Hint: you can use the btInsert predicate from the lecture notes.)
?- list2tree([7,
5, 1, 3, 6, 9] , T).
T = bt(7,
bt(5, bt(1, nil, bt(3, nil, nil)), bt(6, nil,
nil)), bt(9, nil, nil));
No
The above binary tree looks like this:
7
/ \
5
9
/ \
1 6
\
3
b. Implement a predicate that counts the number of
leaves in a tree (a leave is a node with no subtrees:
the left and the right subtrees are both nil). For the previous tree the leaves are 3, 6, and 9.
Example:
?- count_leaves(bt(7, bt(5, bt(1,
nil, bt(3, nil, nil)), bt(6,
nil, nil)), bt(9, nil, nil)), N).
N = 3;
No
c. Implement a predicate that counts the number of
internal nodes of a tree. An internal node has one or two subtrees
that are not empty (not nil). For the previous tree the leaves are 7, 5, and 1.
Example:
?- count(bt(7,
bt(5, bt(1, nil, bt(3, nil, nil)), bt(6, nil,
nil)), bt(9, nil, nil)), N).
N = 3;
No
d. Implement a predicate that traverses a binary tree
in prefix order (visits the node first, then the left subtree,
then the right subtree). The result is the second
argument, a list. Example:
?- tree2list_pre(bt(7, bt(5, bt(1,
nil, bt(3, nil, nil)), bt(6,
nil, nil)), bt(9, nil, nil)),L).
L = [7, 5, 1, 3, 6, 9];
No
e. Implement a predicate that traverses a binary tree
in infix order (visits the left subtree, then the
node, then the right subtree). The result is the
second argument, a list. Example:
?- tree2list_in(bt(7, bt(5, bt(1,
nil, bt(3, nil, nil)), bt(6,
nil, nil)), bt(9, nil, nil)),L).
L = [1, 3, 5, 6, 7, 9];
No
f. Implement a predicate that traverses a binary tree
in postfix order (visits the left subtree, then the
right subtree, and the node at the end). The result
is the second argument, a list. Example:
?- tree2list_post(bt(7, bt(5, bt(1,
nil, bt(3, nil, nil)), bt(6,
nil, nil)), bt(9, nil, nil)),L).
L = [3, 1, 6, 5, 9, 7];
No
Hint: for
part a, you can use the following predicate that takes a new key (a number in
our case) and a binary search tree, and produces a new binary search tree with
the new key inserted in the right position.
btInsert(E, nil, bt(E, nil, nil)).
btInsert(E, bt(E, L, R), bt(E, L, R)).
btInsert(E, bt(E1, L, R), bt(E1, L1, R)) :-
btInsert(E, L, L1), E < E1.
btInsert(E, bt(E1, L, R), bt(E1, L, R1)) :-
btInsert(E, R, R1), E > E1.
Examples of use:
?- btInsert(4,nil,T).
T = bt(4, nil, nil)
?- btInsert(2, bt(4, nil,
nil), T).
T = bt(4, bt(2, nil,
nil), nil)
?- btInsert(5, bt(4, bt(2,
nil, nil), nil), T).
T = bt(4, bt(2, nil,
nil), bt(5, nil, nil))
Have fun!!!