0% found this document useful (0 votes)
41 views10 pages

CS300 Sample Final Solutions

Uploaded by

slymn13
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views10 pages

CS300 Sample Final Solutions

Uploaded by

slymn13
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

CS300 SAMPLE FINAL SOLUTIONS

1)
a) Show the result of inserting 10, 12, 1, 14, 6, 5, 8, 15, 3, 9, 7, 4, 11, 13, and 2, one at a time,
into an initially empty binary heap.
b) Show the result of using the linear-time algorithm to build a binary heap using the same
input.

a) b)

c) Show the result of performing three deleteMin operations in the heap of the
previous exercise.

The result of three deleteMins, starting with both of the heaps in both a and b, is as follows:

2) Show the following regarding the maximum item in the heap:


a. It must be at one of the leaves.
Since each element in a min heap has children whose elements are greater than the value in
the element itself, the maximum element has no children and is a leaf.

b. Every leaf must be examined to find it.


Since the maximum element can be any leaf (the position of a node is determined entirely by
the value of its parent and children), all leaves must be examined to find the maximum value
in a min heap.

3) Prove that for binary heaps, buildHeap does at most 2N−2 comparisons between elements.

We show that H(N), which is the sum of the heights of nodes in a complete binary tree of N
nodes, is N  b(N), where b(N) is the number of ones in the binary representation of N. Observe
that for N = 0 and N = 1, the claim is true. Assume that it is true for values of k up to and
including N  1. Suppose the left and right subtrees have L and R nodes, respectively. Since the

log N 
root has height  , we have

H (N )  log N   H (L )  H (R )
 log N   L  b(L)  R  b(R)
 N  1    Log N   b(L)  b(R ) 
The second line follows from the inductive hypothesis, and the third follows because L + R = N 
1. Now the last node in the tree is in either the left subtree or the right subtree. If it is in the

b(R)  log N   1


left subtree, then the right subtree is a perfect tree, and . Further, the binary
representation of N and L are identical, with the exception that the leading 10 in N becomes 1
in L. (For instance, if N = 37 = 100101, L = 10101.) It is clear that the second digit of N must be
zero if the last node is in the left subtree. Thus in this case, b(L) = b(N), and
H(N) = N  b(N)

b(L)  log N 


If the last node is in the right subtree, then . The binary representation of R
is identical to N, except that the leading 1 is not present. (For instance, if N = 27 = 101011,
L = 01011.) Thus b(R) = b(N)  1, and again
H(N) = N  b(N)

4) Give an algorithm to find all nodes less than some value, X, in a binary heap. Your algorithm
should run in O(K), where K is the number of nodes output.
Perform a preorder traversal of the heap.
5) Suppose we need to perform M percolateUps and N deleteMins on a binary heap that initially has
N elements. What is the running time of all of these heap operations?
O((M + N) log N)

6) Show the result of the following sequence of union instructions on trees representing disjoint
sets: union(1,2), union(3,4), union(3,5), union(1,7), union(3,6), union(8,9), union(1,8),
union(3,10), union (3,11), union(3,12), union(3,13), union(14,15), union(16,0),
union(14,16), union (1,3), union(1, 14) when the unions are:
a. performed arbitrarily
b. performed by height
c. performed by size

We assume that unions operated on the roots of the trees containing the arguments. Also, in case
of ties, the second tree is made a child of the first. Arbitrary union and union by height give the
same answer (shown as the first tree) for this problem. Union by size gives the second tree.

7) For each of the trees in the previous question 12, perform a find with path compression on the
deepest node.

In both cases, have nodes 16 and 0 point directly to the root.

8) Show that if unions are performed by height, then the depth of any tree is O(logN).

Claim: A tree of height h has at least 2h nodes. The proof is by induction. A tree of height 0 clearly
has at least 1 node, and a tree of height 1 clearly has at least 2. Let T be the tree of height h with
fewest nodes. Thus at the time of T’s last union, it must have been a tree of height h  1, since
otherwise T would have been smaller at that time than it is now and still would have been of
height h, which is impossible by assumption of T’s minimality. Since T’s height was updated, it
must have been as a result of a union with another tree of height h  1. By the induction
hypothesis, we know that at the time of the union, T had at least 2h1 nodes, as did the tree
attached to it, for a total of 2h nodes, proving the claim. Thus an N-node tree has depth at most
 log N  .

9) Suppose f (n) is a nicely defined function that reduces n to a smaller integer. What is the solution
to the recurrence T(N) = n/f (n)*T(f (n)) + n with appropriate initial conditions?
We are given T(n) = n/f(n) * T(f(n)) + n

First, we expand T(f(n)) using the definition of T(n) itself:


T(f(n)) = f(n)/f(f(n)) * T(f(f(n))) + n
and then substitute this expression for T(f(n)) into the original formula to obtain
T(n) = n/f(n) * [ f(n)/f(f(n)) * T(f(f(n))) + n ] + n
= n/f(f(n)) * T(f(f(n)) + n2/f(n) + n
Next, we consider T(f(f(n)). We expand this term next:
T(f(f(n))) = f(f(n))/f(f(f(n))) * T(f(f(f(n)))) + n
and then substitute this expression for T(f(f(n))) into the most recent formula we have for T(n).
T(n) = n/f(f(n)) * [ f(f(n))/f(f(f(n))) * T(f(f(f(n)))) + n ] + n 2/f(n) + n
= n/f(f(f(n))) * T(f(f(f(n))) + n2/f(f(n)) + n2/f(n) + n
And, next we expand T(f(f(f(n)))) using the definition of T.
T(f(f(f(n)))) = f(f(f(n)))/f(f(f(f(n)))) * T(f(f(f(f(n))))) + n
and let's substitute into the most recent formula for T.
T(n) = n/f(f(f(n))) * [ f(f(f(n)))/f(f(f(f(n)))) * T(f(f(f(f(n))))) + n] + n 2/f(f(n)) + n2/f(n) + n
= n/f(f(f(f(n)))) * T(f(f(f(f(n))))) + n2/f(f(f(n))) + n2/f(f(n)) + n2/f(n) + n
= n/f(f(f(f(n)))) * T(f(f(f(f(n))))) + n2[1/f(f(f(n)))+1/f(f(n))+1/f(n)] + n
And in general, this can go on indefinitely, and we would obtain
T(n) = n/f k(n) * T(fk(n)) + n2[1/f k–1(n)+1/f k–2(n)+...+1/f(n)] + n
And eventually, fk(n) = 1, so our equation becomes T(n) = n * T(1) + n 2[sum of small fractions] + n.
Let's assume the sum in brackets equals s. We obtain: T(n) = n * T(1) + s*n 2 + n.
We need to assume an initial condition for T(1). Let us assume it is c. Now we have T(n) = cn +
s*n2 + n = s*n2 + (c+1)n. In other words, T(n) is a polynomial of degree 2, or T(n) = O(n 2).

10) Sort the sequence 3, 1, 4, 1, 5, 9, 2, 6, 5 using insertion sort. Show each step.
11) What is the running time of insertion sort if all elements are equal?
O(N), because the while loop terminates immediately. Of course, accidentally
changing the test to include equalities raises the running time to quadratic for this
type of input.

12) What is the running time of Shellsort using the two-increment sequence {1, 2}?
(N2). The 2-sort removes at most only three inversions at a time; hence the algorithm is (N2).
The 2-sort is two insertion sorts of size N/2, so the cost of that pass is O(N2). The 1-sort is also
O(N2), so the total is O(N2).

13) Show how heapsort processes the input 142, 543, 123, 65, 453, 879, 572, 434,111, 242, 811,
102.
The input is read in as
142, 543, 123, 65, 453, 879, 572, 434, 111, 242, 811, 102
The result of the heapify is
879, 811, 572, 434, 543, 123, 142, 65, 111, 242, 453, 102
879 is removed from the heap and placed at the end. We’ll place it in italics to signal that it is
not part of the heap. 102 is placed in the hole and bubbled down, obtaining
811, 543, 572, 434, 453, 123, 142, 65, 111, 242, 102, 879
Continuing the process, we obtain
572, 543, 142, 434, 453, 123, 102, 65, 111, 242, 811, 879
543, 453, 142, 434, 242, 123, 102, 65, 111, 572, 811, 879
453, 434, 142, 111, 242, 123, 102, 65, 543, 572, 811, 879
434, 242, 142, 111, 65, 123, 102, 453, 543, 572, 811, 879
242, 111, 142, 102, 65, 123, 434, 453, 543, 572, 811, 879
142, 111, 123, 102, 65, 242, 434, 453, 543, 572, 811, 879
123, 111, 65, 102, 142, 242, 434, 453, 543, 572, 811, 879
111, 102, 65, 123, 142, 242, 434, 453, 543, 572, 811, 879
102, 65, 111, 123, 142, 242, 434, 453, 543, 572, 811, 879
65, 102, 111, 123, 142, 242, 434, 453, 543, 572, 811, 879

14) What is the running time of heapsort for presorted input?

O(N log N)

15) Sort { 3, 1, 4, 1, 5, 9, 2, 6 } using mergesort. Show each step.

First the sequence {3, 1, 4, 1} is sorted. To do this, the sequence {3, 1} is sorted. This involves
sorting {3} and {1}, which are base cases, and merging the result to obtain {1, 3}. The sequence {4,
1} is likewise sorted into {1, 4}. Then these two sequences are merged to obtain {1, 1, 3, 4}. The
second half is sorted similarly, eventually obtaining {2, 5, 6, 9}. The merged result is then easily
computed as {1, 1, 2, 3, 4, 5, 6, 9}.

16) Determine the running time of mergesort for


a. sorted input
b. reverse-ordered input
c. random input

The merging step always takes (N) time, so the sorting process takes (N log N) time on all
inputs.

17) Sort 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5 using quicksort with median-of-three partitioning and a cutoff of 3.

The original input is


3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5
After sorting the first, middle, and last elements, we have
3, 1, 4, 1, 5, 5, 2, 6, 5, 3, 9
Thus the pivot is 5. Hiding it gives
3, 1, 4, 1, 5, 3, 2, 6, 5, 5, 9
The first swap is between two fives. The next swap has i and j crossing. Thus the pivot is swapped
back with i:
3, 1, 4, 1, 5, 3, 2, 5, 5, 6, 9
We now recursively quicksort the first eight elements:
3, 1, 4, 1, 5, 3, 2, 5
Sorting the three appropriate elements gives
1, 1, 4, 3, 5, 3, 2, 5
Thus the pivot is 3, which gets hidden:
1, 1, 4, 2, 5, 3, 3, 5
The first swap is between 4 and 3:
1, 1, 3, 2, 5, 4, 3, 5
The next swap crosses pointers, so is undone; i points at 5, and so the pivot is swapped:
1, 1, 3, 2, 3, 4, 5, 5
A recursive call is now made to sort the first four elements. The pivot is 1, and the partition does not
make any changes. The recursive calls are made, but the subfiles are below the cutoff, so nothing is
done. Likewise, the last three elements constitute a base case, so nothing is done. We return to the
original call, which now calls quicksort recursively on the right-hand side, but again, there are only
three elements, so nothing is done. The result is
1, 1, 3, 2, 3, 4, 5, 5, 5, 6, 9
which is cleaned up by insertion sort.

18) Write the recurrence T(N) for the average case of quicksort and solve it.
T(0) = 0
N −1
T(N) = (1/N) [ ∑ T (i) ] + cN,
i=0
See slides.

19) Using the quicksort implementation in this chapter, determine the running time of quicksort
for
a. sorted input
O(N log N) because the pivot will partition perfectly.

b. reverse-ordered input
Again, O(N log N) because the pivot will partition perfectly.

c. random input
O(N log N); the performance is slightly better than the analysis suggests because of the
median-of-three partition and cutoff.

20) Repeat Question 25 when the pivot is chosen as:


a. the first element
If the first element is chosen as the pivot, the running time degenerates to quadratic in
the first two cases. It is still O(N log N) for random input.

b. the larger of the first two distinct elements


The same results apply for this pivot choice.

c. a random element
If a random element is chosen, then the running time is O(N log N) expected for all
inputs, although there is an O(N2) worst case if very bad random numbers come up.
There is, however, an essentially negligible chance of this occurring. Chapter 10 of your
textbook discusses the randomized philosophy.

d. the average of all elements in the set


This is a dangerous road to go; it depends on the distribution of the keys. For many
distributions, such as uniform, the performance is O(N log N) on average. For a skewed
distribution, such as with the input {1, 2, 4, 8, 16, 32, 64, . . . ,} the pivot will be
consistently terrible, giving quadratic running time, independent of the ordering of the
input.

21) Construct a permutation of 20 elements that is as bad as possible for quicksort using median-
of-three partitioning and a cutoff of 3.

The strategy used here is to force the worst possible pivot at each stage. This doesn’t necessarily
give the maximum amount of work (since there are few exchanges, just lots of comparisons), but
it does give (N2) comparisons. By working backward, we can arrive at the following
permutation:
20, 3, 5, 7, 9, 11, 13, 15, 17, 19, 4, 10, 2, 12, 6, 14, 1, 16, 8, 18
A method to extend this to larger numbers when N is even is as follows: The first element is N,
the middle is N  1, and the last is N  2. Odd numbers (except 1) are written in decreasing order
starting to the left of center. Even numbers are written in decreasing order by starting at the
rightmost spot, always skipping one available empty slot, and wrapping around when the center
is reached. This method takes O(N log N) time to generate the permutation, but is suitable for a
hand calculation. By inverting the actions of quicksort, it is possible to generate the permutation
in linear time.

22) Find a topological ordering for the graph below:

a. Use a queue and assume that vertices appear on an adjacency list alphabetically.
The topological order that results is then
s, G, D, H, A, B, E, I, F, C, t

b. Use a stack and assume that vertices appear on an adjacency list alphabetically.
s, G, H, D, A, E, I, F, B, C, t
Because a topological sort processes vertices in the same manner as a
breadth-first search, it tends to produce a more natural ordering.

23) Find the shortest path from A to all other vertices for the graph below, show your steps:

A → C, A → B, A → B → G, A → B → G → E, A → B → G → E → F, A → B → G → E → D
24) Find a minimum spanning tree for the graph below using Prim’s algorithm.
Is this minimum spanning tree unique? Why?

One possible minimum spanning tree is shown here. This solution is not unique.
25) Give an algorithm to decide whether an edge (v, w) in a depth-first spanning forest of a
directed graph is a tree, back, cross, or forward edge.

Suppose the vertices are numbered in preorder and postorder.


If (v, w) is a tree edge, then v must have a smaller preorder number than w. It is easy to
see that the converse is true.
If (v, w) is a cross edge, then v must have both a larger preorder and postorder number
than w. The converse is shown as follows: Because v has a larger preorder number, w
cannot be a descendent of v; because it has a larger postorder number, v cannot be a
descendent of w; thus they must be in different trees.
Otherwise, v has a larger preorder number but is not a cross edge. To test if (v, w) is a
back edge, keep a stack of vertices that are active in the depth-first search call (that is, a
stack of vertices on the path from the current root). By keeping a bit array indicating
presence on the stack, we can easily decide if (v, w) is a back edge or a forward edge.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy