CSE326 Midterm Exam #1
With answers and notes
July 9, 2004
Each part of each problem is worth 4 points except where noted
1. In a binary tree, "full nodes" are those with two
children.
A. What is the relationship between the number of
full nodes
and the number of leaves in a binary tree? Iluustrate with a
couple of
examples.
#Leaves=#FullNodes +1. See attatched for examples.
B. Now prove your answer with a careful proof.by
induction.
Note: a very common flaw in the proof was
omitting a statement of what the induction variable was. This
cannot be inferred just from the relationship "#Leaves=#FullNodes
+1". Some possibiities are:
induction on the number of nodes in the tree
induction on the number of leaves
induction on the number of full nodes
induction of the height of the tree, etc.
Each of these will lead
to different ways of phrasing the base case(s), different uses of the
induction hypothesis, etc.
Proof by induction on number of nodes in the graph. Let P(n) = For all trees with n nodes, #Leaves=#FullNodes +1 .
Basis step: For P(1), there is only one possible tree, with
nothing but a root, and for this tree, the statement is true:
#Leaves=1 and #FullNodes=0
Induction Hypothesis: Assume P(k) is true for some k >= 1.
Induction Step: Consider any tree with k+1 nodes. Remove one of the
leaf
nodes. The remaining tree has k nodes, so the ID holds for that tree.
Two cases are possible.
a) the parent of the leaf node removed is a full node. In this case
adding the leaf
increases the number of full nodes by 1 and the number of leaves by 1.
So the
equality is satisfied. b) the parent of leaf node was not a full node.
So when
the leaf is added the number of leaves is unchanged (parent is no
longer a leaf
and a leaf is added) and no extra full nodes are added. so equality is
maintained.
2. Let f and g be functions, and suppose that for every n>1,
it is
true that f(n) < g(n). Clearly f(n) = O(g(n)). Is
it also
possible that g(n) = O(f(n))? Explain.
Yes. Consider f(n)=n and g(n)=2n. Clearly f(n)<g(n). Also
g(n)=O(f(n)) as
g(n)<=3*f(n) for n>1.
3. Suppose the time complexity function of an algorithm is
approximated
at 5*2N. The algorithm is programmed and timed to run
for
about 5 seconds when N = 10. Given just this information,
estimate how
long it would take to run when N = 20.
Remember that the basic definition of a complexity function is that it tells the number of steps required for a given problem size. Use the complexity formulat to find the number of steps for N=10, and you can calculate how long each step takes. Then when you have calculated the number of steps when N=20, you can figure out the total time.
(Time taken for N=20) / (Time taken for N=10) = (5*220 )/( 5*210) = 210 =1024.
So, Time taken for (N=20) is
5*1024=5120s.
Only an
"estimate" was asked for, so you could have rounded off or approximated
along the way. 5000 was certainly acceptable.
4. Each of the following functions is defined at least for
values of n
>= 2. Give a big-Theta bound for each of these
functions. You do
not need to explain your answer. (2 pts. each)
f(n) = n * (n % 7) O(n)
f(n) = n % (n - 1) This is exactly 1. O(1)
f(n) = (n * n) % (n + 1) This is exactly 1. O(1)
5. Outline the steps to solve this problem using the classes,
interfaces, and methods of the Java Collections framework. Give
code that
is pretty close to real, compilable Java if possible (without taking
too much
of your valuable time!).
John and Brenda each have a list of all the books they own.
A. Print out all the books owned by either of
them
(listing each book only once), and then
B. print out only the books they both own.
The solutions
shown are quite compact through clever use of the addAll and contains
method. You can of course solve the problem without them.
List brenda;
List john;
A.
|
B.
|
6. Given an initially empty stack S of characters, what is on the
stack after
these operations have completed? (For possible partial credit,
show your
work).
S.push('s');
S.push('t');
S.push('u');
char ch = S.pop();
ch = S.pop();
S.push('v');
S.push(ch);
S.push('w');
ch = S.pop();
See attatched.
7. Given an initially empty queue Q of characters, what is in
the queue
after these operations have completed? (For possible partial
credit, show
your work).
Q.enqueue('s');
Q.enqueue('t');
Q.enqueue('u');
char ch = Q.dequeue();
ch = Q.dequeue();
Q.enqueue('v');
Q.enqueue(ch);
Q.enqueue('w');
ch = Q.dequeue();
See attached.
8. Think about the stack-based algorithm for evaluating
post-fix
expressions. (You can assume, if it helps, that all the
operations are
binary, left-associative).
A. In terms of that algorithm, how do you determine
whether
a given expression is a valid postfix expression? (For example, A
B + is
valid but Z + Y is not).
The given expression is valid postfix if
1) The stack contains atleast two elements whenever you try to pop two elements. (i.e. StackEmptyException is never thrown).
2) The stack contains exactly
one element when the expression is completely read.
B. Give an algorithm for determining if a given
expression
is valid postfix or not. Do not use a stack (do something simpler
if
possible).
Keep a counter of "effective" number of operands. Initialize
the counter to 0. Whenever you see
an operand, add one to this counter. When you see an operator check to
see if the
number of operands is >=2. if not the expression is malformed; if
yes,
decrement the counter by one. At the end of the expression the value of
counter should
be 1 for the expression to be well formed.
9. There is a stack-based algorithm for converting in-fix
expressions
into postfix. Show how this works, by showing the state of the
stack and
the output at each step during the conversion of this
expression.
You can do this by crossing out old values if you are neat and clear
about it;
otherwise, redraw the stack at each stage.
A * (B + C / D) + E
See attatched.
10. Suppose you are told that A B C D is the pre-order traversal
of a
binary tree, and that A B C D is also the in-order traversal of
the same
tree! Either give a tree which satisfies this, or explain why it
is not
possible.
It is possible. Note that is there is no left child the actions of
the two
traversals are identical. See attached to example of tree.
11. Draw the tree resulting from inserting the following values
into an
initially empty binary search tree:
5 10 20 3 7
4
1 6 11 19
See attached.
12. Give worst-case and average-case bounds (big-Theta if
possible,
otherwise just big-O) for the time of each of the following, assuming a
reasonable implementation (2 pts. each):
A. Insertion into a queue (array-based
implementation) Theta(1)
B. Deletion from a binary search tree Theta(log(n))
average case, assuming the tree is reasonably well balanced on
average. Worst-case Theta(n).
C. Finding the max value in a binary search tree See
previous answer
D. Deletion from a list (linked-list implementation)
Theta(1), assuming you know where the deletion is to be; Theta(n) if
you have to search for the element
E. Insertion in a list at given position
(array-based implementation)
Theta(1) if you take "insertion" to mean "replacement",
Theta(n) if insertion means preserving the elements in the list by
shifting to the right (e.g, the way Java ArrayList works).
13. In this problem, we deal exclusively with binary trees
of
integers. It might help you to think of these integers as
weights, and to
think of the tree like an Alexander Calder mobile with objects of
different
weights dangling from it.
Define a node to be "weight-balanced" if the sum of all the weights
(i.e., the integer values) in the left subtree is equal to the sum of
all the
weights in the right subtree. Note that with this definition,
every leaf
node is weight-balanced.
A (2 pts.) Give an example of a tree (with 4 or more nodes) whose
root is
weight-balanced but where no other non-leaf nodes are weight-balanced. See
attatched.
B. (2 pts.) Give an example of a tree (with 4 or more nodes) in which
every
node is weight-balanced. See attatched.
C. (2 pts.) Give an example of a binary search tree (with 4 or
more
nodes) in which the root is weight-balanced.See attatched.
D. (8 pts.) Implement the following method in Java:
/** Return true iff the node is weight-balanced or is null.*.
boolean checkBalance(BinTreeNode node);
Use this class definition:
public class BinTreeNode {
Object element;
BinTreeNode left;
BinTreeNode right;
}
Your are free to write helper methods if you wish.
public static boolean checkBalance(BinTreeNode node) {
E. Give a bound for the running time of your algorithm (2 pts.) O(n).
if (node == null) {
return true;
}
return sum(node.left) == sum(node.right);
}
private static int sum(BinTreeNode node) {
if (node == null) {
return 0;
}
return ((Integer) node.element).intValue()
+ sum(node.left) + sum(node.right);
}