You are on page 1of 16

Test 2: CPS 100

Owen Astrachan
November 10, 2004
Name:
Login:
Honor code acknowledgment (signature)
value grade
Problem 1 22 pts.
Problem 2 20 pts.
Problem 3 22 pts.
TOTAL: 64 pts.
This test has 14 pages, be sure your test has them all. Do NOT spend too much time on one question
remember that this class lasts 75 minutes.
In writing code you do not need to worry about specifying the proper import statements. Assume that all
libraries and packages weve discussed are imported in any code you write.
1
Some common recurrences and their solutions.
A T(n) = T(n/2) + O(1) O(log n)
B T(n) = T(n/2) + O(n) O(n)
C T(n) = 2T(n/2) + O(1) O(n)
D T(n) = 2T(n/2) + O(n) O(nlog n)
E T(n) = T(n-1) + O(1) O(n)
F T(n) = T(n-1) + O(n) O(n
2
)
G T(n) = 2T(n-1) + O(1) O(2
n
)
The class TreeNode used on this test.
public static class TreeNode {
String info;
TreeNode left;
TreeNode right;
TreeNode(String val, TreeNode lptr, TreeNode rptr)
{
info = val;
left = lptr;
right = rptr;
}
}
2
PROBLEM 1 : (Simple Stu (22 points))
"grizzly"
"koala"
"brown"
"kodiak"
"polar"
"teddy" "panda"
Part A (3 points)
What is the preorder traversal of the search tree above whose root is "koala"?
Part B (3 points)
The height of a tree is the number of edges on the longest root-to-leaf path, the height of the bear tree above
is three. Draw another search tree with the same values, but whose height is two (you may need a dierent
bear at the root of the new tree you draw).
3
Part C (4 points)
The method count below returns the number of nodes in a tree.
public static int count(TreeNode t){
if (t == null) return 0;
return 1 + count(t.left) + count(t.right);
}
The depth of a node is the number of edges from the root to the node. In the bear tree above "panda",
"teddy", and "brown" have depth two; "kodiak" has depth three.
Write the method depthCount that returns the number of nodes with the specied depth. The root of a tree
has depth zero.
/**
* Returns number of nodes at specified depth in Tree t.
*/
public static int depthCount(TreeNode t, int depth){
}
4
Part D (4 points)
Write the method twoChildCount that returns the number of nodes that have two children in a tree. For
the tree above the method should return two since only "polar" and "koala" have two children.
/**
* Returns number of nodes with two children in t.
*/
public static int twoChildCount(TreeNode t){
}
5
Part E (4 points)
The method longest below returns the length of the longest string in a tree. What is the big-Oh complexity
of this method and why (Justify your answer).
/**
* Return length of longest string in tree with given root.
*/
public static int longest(TreeNode root){
if (root == null) return 0;
return Math.max(root.info.length(),
Math.max(longest(root.left),
longest(root.right)));
}
Part F (4 points)
The method reverse below reverses the links in a linked list so that the list shown on the left is changed to
the list on the right by re-arranging links as a result of executing list = reverse(list).
(ape, gorilla, monkey, orangutan) (orangutan, monkey, gorilla, ape)
What is the complexity of reverse? Justify your answer.
public static class Node{
String info;
Node next;
Node(String val, Node link){
info = val;
next = link;
}
}
public static Node reverse(Node n){
if (n == null || n.next == null) return n; // no nodes or 1, done
Node afterMe = reverse(n.next); // reverse rest
// now find end of reversed list and link to me
Node temp = afterMe;
while (temp.next != null){
temp = temp.next;
}
temp.next = n;
n.next = null;
return afterMe;
}
6
PROBLEM 2 : (Trees and Lists oh My (20 points))
In this problem youll write methods to convert a sorted ArrayList to a balanced binary search tree con-
taining the same values stored in the ArrayList, and vice versa: a method to convert a tree to a sorted list.
The picture below shows one example of a list and the tree that corresponds to the list. (the tree shows
numbers, but Strings are stored in the tree, see the declarations at the beginning of this test).
5 7 17 15 13 11 9 19 23 21 15
9 21
7 13 19 23
5 11 17
Part A (5 points)
The method tree2list returns a sorted ArrayList containing the same values as the tree passed to the
method. The general algorithm for the helper method tree2listAux is to perform an inorder traversal
of the tree, adding a tree value to the list when the tree node is visited during the traversal. Since the
inorder traversal of a search tree visits nodes in sorted order, the resulting list will be sorted. Complete the
method tree2listAux, you should not write more than four statements and you may not modify the code
in tree2list.
/**
* Return sorted list containing same values stored in search tree t.
* @param t is a search tree
* @return sorted list containing same values in t
*/
public static ArrayList tree2list(TreeNode t){
ArrayList list = new ArrayList();
tree2listAux(t,list);
return list;
}
/**
* Add values of tree to list in sorted order.
* @param list stores values (in order) already visited
* @param root is the root of the (sub) tree to be added to list
*/
private static void tree2listAux(TreeNode root, ArrayList list){
if (root != null){
}
}
7
Part B (5 points)
The general algorithm for converting a list to a tree is:
Find the root of the tree, which is the middle element of the list.
Make a node for the root, and recursively make left and right subtrees.
The method list2tree calls a helper method that does the work, the helper method has parameters in-
dicating the range in the list that is converted to a tree. Complete list2treeAux so that it works as
specied.
/**
* Returns balanced tree from sorted list.
* @param list is sorted
* @return balanced search tree containing same values in list
*/
public static TreeNode list2tree(ArrayList list){
return list2treeAux(list,0,list.size()-1);
}
/**
* Return balanced tree consisting of values in list in range
* list[first]..list[last], including first and last, where list
* is sorted. Returns null if first > last.
* @param list is sorted
* @param first is first index of list to be put into tree
* @param last is last index of list to be put into tree
* @return balanced tree containing values list[first]..list[last]
*/
private static TreeNode list2treeAux(ArrayList list, int first, int last){
if (first > last) return null;
int mid = (first + last)/2;
String rootValue = (String) list.get(mid);
// add code here
}
8
Part C (3 points)
Write a recurrence relation for the code you wrote for Part A. Justify the recurrence and indicate what its
big-Oh solution is.
Part D (3 points)
Write a recurrence relation for the code you wrote for Part B. Justify the recurrence. (If you wrote the
simplest code for Part B the solution should be O(n) for an n-element array.)
Part E (4 points)
Suppose you want to convert a sorted linked-list into a search tree. Using the algorithm for Part B above
yields an O(nlog n) solution because nding the middle element takes O(n) time. Explain why this results
in an O(nlog n) algorithm and explain how to do the conversion in O(n) time by rst creating an array from
the linked list.
9
PROBLEM 3 : (Mercator Projection (22 points))
The code handout at the end of this test shows a main that reads a le and creates a map in which keys are
the words in the le and the value corresponding to a key is a Counter that indicates how many time the
word occurs in the le. Part of the code is reproduced below.
Scanner s = new Scanner(f);
Map m = new TreeMap();
while (s.hasNext()){
String str = (String) s.next();
Counter c = (Counter) m.get(str);
if (c == null){
m.put(str, new Counter());
}
else {
c.increment();
}
}
Part A (4 points)
Complete the code fragment below so that it correctly stores in smax the word that occurs most frequently,
and stores the number of occurrences of this word in max.
int max = 0; // most frequent occurrences
String smax = null; // most frequently occurring word
Iterator it = m.keySet().iterator();
while (it.hasNext()){
String str = (String) it.next();
}
System.out.println("most frequent "+smax + " "+max);
10
Three methods are shown in the code at the end of the test: topThirty1, topThirty2, and topThirty3.
Each does the same thing: returns an array of the 30 most-frequently occurring words in order so that the
rst element in the returned array is the most frequently occurring word, the second element in the array is
the second most frequently occurring word, and so on. Each of the three methods works correctly. Youll be
asked questions about each method which are reproduced below.
Part B (6 points)
Recall that the class Map.Entry stores both the key and the corresponding value of an entry in a map; both
the key and the value can be obtained as shown in the code below.
Explain in words why the method topThirty1 returns an array with the most frequently occurring word
in the map stored at index 0 of the array, the second most frequently occurring word stored at index 1, and
so on. You should mention how the Comparator works in the code.
private static class EntryComparator implements Comparator{
public int compare(Object o1, Object o2) {
Map.Entry me1 = (Map.Entry) o1;
Map.Entry me2 = (Map.Entry) o2;
Counter c1 = (Counter) me1.getValue();
Counter c2 = (Counter) me2.getValue();
return c2.getValue() - c1.getValue();
}
}
public static String[] topThirty1(Map m){
ArrayList list = new ArrayList(m.entrySet());
Collections.sort(list, new EntryComparator());
String[] a = new String[30];
for(int k=0; k < 30; k++){
Map.Entry entry = (Map.Entry) list.get(k);
a[k] = (String)entry.getKey();
}
return a;
}
11
Part C (6 points)
The method topThirty2 below uses a PriorityQueue to obtain the 30 most frequently occurring words in a
map.
Explain in words why the EntryComparator is needed when creating the priority queue and what the
big-Oh complexity of the method below is for nding the top 30 words in a map with N elements. Justify
your answer.
public static String[] topThirty2(Map m){
PriorityQueue pq = new PriorityQueue(new EntryComparator());
pq.addAll(m.entrySet());
String[] list = new String[30];
for(int k=0; k < 30; k++){
Map.Entry entry = (Map.Entry) pq.remove();
list[k] = (String)entry.getKey();
}
return list;
}
12
Part D (6 points)
The code below also uses a PriorityQueue, but never stores more than 30 elements in the queue. Explain
three things: (A) why the class RevComp is used in the code; (B) why the index 30-k-1 is used in the
statement below
list[30-k-1] = (String) entry.getKey();
instead of using list[k]; and (C) why this method is more ecient than the other two methods. Justify
your answers.
private static class RevComp implements Comparator{
Comparator myComp;
public RevComp(Comparator c){
myComp = c;
}
public int compare(Object o1, Object o2){
return -1*myComp.compare(o1,o2);
}
}
public static String[] topThirty3(Map m){
PriorityQueue pq = new PriorityQueue(new RevComp(new EntryComparator()));
Iterator it = m.entrySet().iterator();
while (it.hasNext()){
pq.add(it.next());
if (pq.size() > 30){
pq.remove();
}
}
String[] list = new String[30];
for(int k=0; k < 30; k++){
Map.Entry entry = (Map.Entry) pq.remove();
list[30-k-1] = (String) entry.getKey();
}
return list;
}
13
nothing on this page
14
i
m
p
o
r
t

j
a
v
a
.
i
o
.
F
i
l
e
;
i
m
p
o
r
t

j
a
v
a
.
u
t
i
l
.
*
;
i
m
p
o
r
t

j
a
v
a
x
.
s
w
i
n
g
.
J
F
i
l
e
C
h
o
o
s
e
r
;
c
l
a
s
s

C
o
u
n
t
e
r

{








p
r
i
v
a
t
e

i
n
t

m
y
C
o
u
n
t
;




/
*
*





*

C
o
n
s
t
r
u
c
t

a

c
o
u
n
t
e
r

w
h
o
s
e

v
a
l
u
e

i
s

z
e
r
o





*
/




p
u
b
l
i
c

C
o
u
n
t
e
r
(
)

{








t
h
i
s
(
1
)
;




}




p
u
b
l
i
c

C
o
u
n
t
e
r
(
i
n
t

v
a
l
u
e
)

{








m
y
C
o
u
n
t

=

v
a
l
u
e
;




}




/
*
*





*

R
e
t
u
r
n
s

t
h
e

v
a
l
u
e

o
f

t
h
e

c
o
u
n
t
e
r
.





*

@
r
e
t
u
r
n

t
h
e

v
a
l
u
e

o
f

t
h
e

c
o
u
n
t
e
r





*
/




p
u
b
l
i
c

i
n
t

g
e
t
V
a
l
u
e
(
)

{








r
e
t
u
r
n

m
y
C
o
u
n
t
;




}




/
*
*





*

Z
e
r
o
s

t
h
e

c
o
u
n
t
e
r

s
o

g
e
t
V
a
l
u
e
(
)

=
=

0
.





*
/




p
u
b
l
i
c

v
o
i
d

c
l
e
a
r
(
)

{








m
y
C
o
u
n
t

=

0
;




}




/
*
*





*

I
n
c
r
e
a
s
e

t
h
e

v
a
l
u
e

o
f

t
h
e

c
o
u
n
t
e
r

b
y

o
n
e
.





*
/




p
u
b
l
i
c

v
o
i
d

i
n
c
r
e
m
e
n
t
(
)

{








m
y
C
o
u
n
t
+
+
;




}




/
*
*





*

R
e
t
u
r
n

a

s
t
r
i
n
g

r
e
p
r
e
s
e
n
t
i
n
g

t
h
e

v
a
l
u
e

o
f

t
h
i
s

c
o
u
n
t
e
r
.





*
/








p
u
b
l
i
c

S
t
r
i
n
g

t
o
S
t
r
i
n
g
(
)
{








r
e
t
u
r
n

"
"
+
m
y
C
o
u
n
t
;




}
} p
u
b
l
i
c

c
l
a
s
s

T
e
s
t
2

{




p
r
i
v
a
t
e

s
t
a
t
i
c

J
F
i
l
e
C
h
o
o
s
e
r

o
u
r
C
h
o
o
s
e
r

=

n
e
w

J
F
i
l
e
C
h
o
o
s
e
r
(
"
.
"
)
;









p
r
i
v
a
t
e

s
t
a
t
i
c

c
l
a
s
s

T
r
e
e
N
o
d
e

{









S
t
r
i
n
g

i
n
f
o
;









T
r
e
e
N
o
d
e


l
e
f
t
;









T
r
e
e
N
o
d
e


r
i
g
h
t
;









T
r
e
e
N
o
d
e
(
S
t
r
i
n
g

v
a
l
,

T
r
e
e
N
o
d
e


l
p
t
r
,

T
r
e
e
N
o
d
e


r
p
t
r
)









{













i
n
f
o

=

v
a
l
;













l
e
f
t

=

l
p
t
r
;













r
i
g
h
t

=

r
p
t
r
;









}





}





p
r
i
v
a
t
e

s
t
a
t
i
c

c
l
a
s
s

E
n
t
r
y
C
o
m
p
a
r
a
t
o
r

i
m
p
l
e
m
e
n
t
s

C
o
m
p
a
r
a
t
o
r
{









p
u
b
l
i
c

i
n
t

c
o
m
p
a
r
e
(
O
b
j
e
c
t

o
1
,

O
b
j
e
c
t

o
2
)

{













M
a
p
.
E
n
t
r
y

m
e
1

=

(
M
a
p
.
E
n
t
r
y
)

o
1
;
N
o
v

1
0
,

0
4

1
:
2
4
P
a
g
e

1
/
3
T
e
s
t
2
.
j
a
v
a













M
a
p
.
E
n
t
r
y

m
e
2

=

(
M
a
p
.
E
n
t
r
y
)

o
2
;













C
o
u
n
t
e
r

c
1

=

(
C
o
u
n
t
e
r
)

m
e
1
.
g
e
t
V
a
l
u
e
(
)
;













C
o
u
n
t
e
r

c
2

=

(
C
o
u
n
t
e
r
)

m
e
2
.
g
e
t
V
a
l
u
e
(
)
;













r
e
t
u
r
n

c
2
.
g
e
t
V
a
l
u
e
(
)


c
1
.
g
e
t
V
a
l
u
e
(
)
;









}














}





p
r
i
v
a
t
e

s
t
a
t
i
c

c
l
a
s
s

R
e
v
C
o
m
p

i
m
p
l
e
m
e
n
t
s

C
o
m
p
a
r
a
t
o
r
{









C
o
m
p
a
r
a
t
o
r

m
y
C
o
m
p
;









p
u
b
l
i
c

R
e
v
C
o
m
p
(
C
o
m
p
a
r
a
t
o
r

c
)
{













m
y
C
o
m
p

=

c
;









}









p
u
b
l
i
c

i
n
t

c
o
m
p
a
r
e
(
O
b
j
e
c
t

o
1
,

O
b
j
e
c
t

o
2
)
{













r
e
t
u
r
n

1
*
m
y
C
o
m
p
.
c
o
m
p
a
r
e
(
o
1
,
o
2
)
;









}





}










p
u
b
l
i
c

s
t
a
t
i
c

S
t
r
i
n
g
[
]

t
o
p
T
h
i
r
t
y
2
(
M
a
p

m
)
{


















P
r
i
o
r
i
t
y
Q
u
e
u
e

p
q

=

n
e
w

P
r
i
o
r
i
t
y
Q
u
e
u
e
(
n
e
w

E
n
t
r
y
C
o
m
p
a
r
a
t
o
r
(
)
)
;









p
q
.
a
d
d
A
l
l
(
m
.
e
n
t
r
y
S
e
t
(
)
)
;









S
t
r
i
n
g
[
]

l
i
s
t

=

n
e
w

S
t
r
i
n
g
[
3
0
]
;









f
o
r
(
i
n
t

k
=
0
;

k

<

3
0
;

k
+
+
)
{













M
a
p
.
E
n
t
r
y

e
n
t
r
y

=

(
M
a
p
.
E
n
t
r
y
)

p
q
.
r
e
m
o
v
e
(
)
;













l
i
s
t
[
k
]

=

(
S
t
r
i
n
g
)
e
n
t
r
y
.
g
e
t
K
e
y
(
)
;









}

r
e
t
u
r
n

l
i
s
t
;





}





p
u
b
l
i
c

s
t
a
t
i
c

S
t
r
i
n
g
[
]

t
o
p
T
h
i
r
t
y
3
(
M
a
p

m
)
{









P
r
i
o
r
i
t
y
Q
u
e
u
e

p
q

=

n
e
w

P
r
i
o
r
i
t
y
Q
u
e
u
e
(
n
e
w

R
e
v
C
o
m
p
(
n
e
w

E
n
t
r
y
C
o
m
p
a
r
a
t
o
r
(
)
)
)
;









I
t
e
r
a
t
o
r

i
t

=

m
.
e
n
t
r
y
S
e
t
(
)
.
i
t
e
r
a
t
o
r
(
)
;









w
h
i
l
e

(
i
t
.
h
a
s
N
e
x
t
(
)
)
{













p
q
.
a
d
d
(
i
t
.
n
e
x
t
(
)
)
;













i
f

(
p
q
.
s
i
z
e
(
)

>

3
0
)
{

















p
q
.
r
e
m
o
v
e
(
)
;













}









}









S
t
r
i
n
g
[
]

l
i
s
t

=

n
e
w

S
t
r
i
n
g
[
3
0
]
;









f
o
r
(
i
n
t

k
=
0
;

k

<

3
0
;

k
+
+
)
{













M
a
p
.
E
n
t
r
y

e
n
t
r
y

=

(
M
a
p
.
E
n
t
r
y
)

p
q
.
r
e
m
o
v
e
(
)
;













l
i
s
t
[
3
0

1
]

=

(
S
t
r
i
n
g
)
e
n
t
r
y
.
g
e
t
K
e
y
(
)
;









}

r
e
t
u
r
n

l
i
s
t
;





}










p
u
b
l
i
c

s
t
a
t
i
c

S
t
r
i
n
g
[
]

t
o
p
T
h
i
r
t
y
1
(
M
a
p

m
)
{









A
r
r
a
y
L
i
s
t

l
i
s
t

=

n
e
w

A
r
r
a
y
L
i
s
t
(
m
.
e
n
t
r
y
S
e
t
(
)
)
;









C
o
l
l
e
c
t
i
o
n
s
.
s
o
r
t
(
l
i
s
t
,

n
e
w

E
n
t
r
y
C
o
m
p
a
r
a
t
o
r
(
)
)
;









S
t
r
i
n
g
[
]

a

=

n
e
w

S
t
r
i
n
g
[
3
0
]
;









f
o
r
(
i
n
t

k
=
0
;

k

<

3
0
;

k
+
+
)
{













M
a
p
.
E
n
t
r
y

e
n
t
r
y

=

(
M
a
p
.
E
n
t
r
y
)

l
i
s
t
.
g
e
t
(
k
)
;













a
[
k
]

=

(
S
t
r
i
n
g
)
e
n
t
r
y
.
g
e
t
K
e
y
(
)
;









}

r
e
t
u
r
n

a
;





}
N
o
v

1
0
,

0
4

1
:
2
4
P
a
g
e

2
/
3
T
e
s
t
2
.
j
a
v
a
P
r
i
n
t
e
d

b
y

O
w
e
n

L
.

A
s
t
r
a
c
h
a
n
W
e
d
n
e
s
d
a
y

N
o
v
e
m
b
e
r

1
0
,

2
0
0
4
1
/
2
T
e
s
t
2
.
j
a
v
a









p
u
b
l
i
c

s
t
a
t
i
c

v
o
i
d

m
a
i
n
(
S
t
r
i
n
g
[
]

a
r
g
s
)
{


















i
n
t

r
e
t
v
a
l

=

o
u
r
C
h
o
o
s
e
r
.
s
h
o
w
O
p
e
n
D
i
a
l
o
g
(
n
u
l
l
)
;









i
f

(
r
e
t
v
a
l

=
=

J
F
i
l
e
C
h
o
o
s
e
r
.
A
P
P
R
O
V
E
_
O
P
T
I
O
N
)
{













F
i
l
e

f

=

o
u
r
C
h
o
o
s
e
r
.
g
e
t
S
e
l
e
c
t
e
d
F
i
l
e
(
)
;















S
c
a
n
n
e
r

s

=

n
e
w

S
c
a
n
n
e
r
(
f
)
;













M
a
p

m

=

n
e
w

T
r
e
e
M
a
p
(
)
;


















w
h
i
l
e

(
s
.
h
a
s
N
e
x
t
(
)
)
{

















S
t
r
i
n
g

s
t
r

=

(
S
t
r
i
n
g
)

s
.
n
e
x
t
(
)
;

















C
o
u
n
t
e
r

c

=

(
C
o
u
n
t
e
r
)

m
.
g
e
t
(
s
t
r
)
;

















i
f

(
c

=
=

n
u
l
l
)
{





















m
.
p
u
t
(
s
t
r
,

n
e
w

C
o
u
n
t
e
r
(
)
)
;

















}

















e
l
s
e

{





















c
.
i
n
c
r
e
m
e
n
t
(
)
;

















}













}





S
t
r
i
n
g
[
]

l
i
s
t
1

=

t
o
p
T
h
i
r
t
y
1
(
m
)
;





S
t
r
i
n
g
[
]

l
i
s
t
2

=

t
o
p
T
h
i
r
t
y
2
(
m
)
;





S
t
r
i
n
g
[
]

l
i
s
t
3

=

t
o
p
T
h
i
r
t
y
3
(
m
)
;









}





}
}
N
o
v

1
0
,

0
4

1
:
2
4
P
a
g
e

3
/
3
T
e
s
t
2
.
j
a
v
a
P
r
i
n
t
e
d

b
y

O
w
e
n

L
.

A
s
t
r
a
c
h
a
n
W
e
d
n
e
s
d
a
y

N
o
v
e
m
b
e
r

1
0
,

2
0
0
4
2
/
2
T
e
s
t
2
.
j
a
v
a

You might also like