






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
This is solution manual provided by Muhammad Uzair at University of Engineering and Technology Lahore. It related to Data Structures and Algorithms course. Its main points are: Algorithm, Designing, Techniques, Processor, Push, Comine, Multinode, Trees, Stack, Queues
Typology: Exercises
1 / 12
This page cannot be seen from the preview
Don't miss anything!







By:
Muhammad Uzair
05-E-
U.E.T. Lahore
Pakistan
Preface
Included in this manual are answers to most of the exercises in the textbook Data Structures and Algorithm Analysis in C, second edition, published by Addison-Wesley. These answers reflect the state of the book in the first printing.
Specifically omitted are likely programming assignments and any question whose solu- tion is pointed to by a reference at the end of the chapter. Solutions vary in degree of complete- ness; generally, minor details are left to the reader. For clarity, programs are meant to be pseudo-C rather than completely perfect code.
Errors can be reported to [email protected]. Thanks to Grigori Schwarz and Brian Harvey for pointing out errors in previous incarnations of this manual.
Chapter 10: Algorithm Design Techniques
10.1 First, we show that if N O evenly divides P O, then each of P j O( i O−1) P O+ 1 through P j (^) iP O must be placed as the i O th O^ job on some processor. Suppose otherwise. Then in the supposed optimal ordering, we must be able to find some jobs P jx O and P jy O such that P jx O is the t O th O^ job on some processor and P jy O is the t O+ 1 th O^ job on some processor but t (^) x O > ty O. Let P jz O be the job immediately following P jx O. If we swap P jy O and P jz O, it is easy to check that the mean pro- cessing time is unchanged and thus still optimal. But now P j (^) y O follows P jx O, which is impos- sible because we know that the jobs on any processor must be in sorted order from the results of the one processor case. Let P je O 1 , P je O 2 , ..., P j (^) eM O be the extra jobs if N O does not evenly divide P O. It is easy to see that the processing time for these jobs depends only on how quickly they can be scheduled, and that they must be the last scheduled job on some processor. It is easy to see that the first M O processors must have jobs P j O( i O−1) P O+ 1 through P jiP O+ M O; we leave the details to the reader.
sp
nl 3 :
10.4 One method is to generate code that can be evaluated by a stack machine. The two opera- tions are Push O (the one node tree corresponding to) a symbol onto a stack and Combine, O which pops two trees off the stack, merges them, and pushes the result back on. For the example in the text, the stack instructions are Push(s), Push(nl), Combine, Push(t), Com- bine, Push(a), Combine, Push(e), Combine, Push(i), Push (sp), Combine, Combine. By encoding a Combine O with a 0 and a Push O with a 1 followed by the symbol, the total extra space is 2 N O − 1 bits if all the symbols are of equal length. Generating the stack machine code can be done with a simple recursive procedure and is left to the reader.
10.6 Maintain two queues, Q O 1 and Q O 2. Q O 1 will store single-node trees in sorted order, and Q O 2 will store multinode trees in sorted order. Place the initial single-node trees on Q O 1 , enqueueing the smallest weight tree first. Initially, Q O 2 is empty. Examine the first two entries of each of Q O 1 and Q O 2 , and dequeue the two smallest. (This requires an easily implemented extension to the ADT.) Merge the tree and place the result at the end of Q O 2. Continue this step until Q O 1 is empty and only one tree is left in Q O 2.
10.9 To implement first fit, we keep track of bins b (^) i O, which have more room than any of the lower numbered bins. A theoretically easy way to do this is to maintain a splay tree ordered by empty space. To insert w O, we find the smallest of these bins, which has at least w O empty space; after w O is added to the bin, if the resulting amount of empty space is less than the inorder predecessor in the tree, the entry can be removed; otherwise, a DecreaseKey O is performed. To implement best fit, we need to keep track of the amount of empty space in each bin. As before, a splay tree can keep track of this. To insert an item of size w O, perform an insert of w O. If there is a bin that can fit the item exactly, the insert will detect it and splay it to the root; the item can be added and the root deleted. Otherwise, the insert has placed w O at the root (which eventually needs to be removed). We find the minimum element M O in the right subtree, which brings M O to the right subtree’s root, attach the left subtree to M O, and delete w O. We then perform an easily implemented DecreaseKey O on M O to reflect the fact that the bin is less empty.
10.10 Next fit: 12 bins (.42, .25, .27), (.07, .72), (.86, .09), (.44, .50), (.68), (.73), (.31), (.78, .17), (.79), (.37), (.73, .23), (.30). First fit: 10 bins (.42, .25, .27), (.07, .72, .09), (.86), (.44, .50), (.68, .31), (.73, .17), (.78), (.79), (.37, .23, .30), (.73). Best fit: 10 bins (.42, .25, .27), (.07, .72, .09), (.86), (.44, .50), (.68, .31), (.73, .23), (.78, .17), (.79), (.37, .30 ), (.73). First fit decreasing: 10 bins (.86, .09), (.79, .17), (.78, .07), (.73, .27), (.73, .25), (.72, .23), (.68, .31), (.50, .44), (.42, .37), (.30). Best fit decreasing: 10 bins (.86, .09), (.79, .17), (.78), (.73, .27), (.73, .25), (.72, .23), (.68, .31), (.50, .44), (.42, .37, .07), (.30). Note that use of 10 bins is optimal.
10.12 We prove the second case, leaving the first and third (which give the same results as Theorem 10.6) to the reader. Observe that log p O N O = log p O( b O m O) = m O p Olog p O b O Working this through, Equation (10.9) becomes
T O( N O) = T O( b O m O) = a O m O i O= 0
m O
D a
____b_ O k O O
i O i O p Olog p O b O
If a O = b O k O, then
T O( N O) = a O m Olog p O b O i O= 0
m i O p O
= O O( a O m O m O p O+^1 log p O b O) Since m O = log N O / log b O, and a O m O^ = N O k O, and b O is a constant, we obtain T O( N O) = O O( N O k Olog p O+^1 N O)
10.13 The easiest way to prove this is by an induction argument.
These mean and variance equations imply
Rv O 1 , S' O ≥ k ( N O+1)
________ ( s O+1) (^) − d O√M s MOO
and
Rv O 2 , S' O ≤ k ( N O+1)
________ ( s O+1) (^) + d O√M s MOO
This gives equation (A): δ = d O√M s MOO = √M s MOOlog 1 /^^2 N O (A)
If we first pivot around v O 2 , the cost is N O comparisons. If we now partition elements in S O that are less than v O 2 around v O 1 , the cost is Rv O 2 , S O, which has expected value k O + δ s O+ 1
Thus the total cost of partitioning is N O + k O + δ s O+ 1
. The cost of the selections to find v O 1 and v O 2 in the sample S' O is O O( s O). Thus the total expected number of comparisons is
N O + k O + O O( s O) + O O( N Oδ / s O) The low order term is minimized when s O = N Oδ / s O (B)
Combining Equations (A) and (B), we see that s O^2 = N Oδ = √M s MO N Olog 1 /^^2 N O (C) s O^3 /^^2 = N Olog 1 /^^2 N O (D) s O = N O^2 /^^3 log 1 /^^3 N O (E) δ = N O^1 /^^3 log 2 /^^3 N O (F)
10.22 First, we calculate 1243. In this case, XL O = 1, XR O = 2, YL O = 4, YR O = 3, D O 1 = −1, D O 2 = −1, XL O YL O = 4, XR O YR O = 6, D O 1 D O 2 = 1, D O 3 = 11, and the result is 516. Next, we calculate 3421. In this case, XL O = 3, XR O = 4, Y (^) L O = 2, Y (^) R O = 1, D O 1 = −1, D O 2 = −1, XL O YL O = 6, XR O YR O = 4, D O 1 D O 2 = 1, D O 3 = 11, and the result is 714. Third, we calculate 2222. Here, XL O = 2, XR O = 2, YL O = 2, YR O = 2, D O 1 = 0, D O 2 = 0, XL O YL O = 4, XR O YR O = 4, D O 1 D O 2 = 0, D O 3 = 8, and the result is 484. Finally, we calculate 12344321. XL O = 12, XR O = 34, YL O = 43, YR O = 21, D O 1 = −22, D O 2 = −2. By previous calculations, XL O YL O = 516, XR O YR O = 714, and D O 1 D O 2 = 484. Thus D O 3 = 1714, and the result is 714 + 171400 + 5160000 = 5332114.
10.23 The multiplication evaluates to ( ac O − bd O) + ( bc O + ad O) i O. Compute ac O, bd O, and ( a O − b O)( d O − c O) + ac O + bd O.
10.24 The algebra is easy to verify. The problem with this method is that if X O and Y O are posi- tive N O bit numbers, their sum might be an N O+1 bit number. This causes complications.
10.26 Matrix multiplication is not commutative, so the algorithm couldn’t be used recursively on matrices if commutativity was used.
10.27 If the algorithm doesn’t use commutativity (which turns out to be true), then a divide and conquer algorithm gives a running time of O O( N Olog^70 143640 ) = O O( N O2.795).
10.28 1150 scalar multiplications are used if the order of evaluation is
( ( A O 1 A O 2 ) ( ( ( A O 3 A O 4 ) A O 5 ) A O 6 ) )
10.29 (a) Let the chain be a 1x1 matrix, a 1xA matrix, and an AxB matrix. Multiplication by using the first two matrices first makes the cost of the chain A O + AB O. The alternative method gives a cost of AB O + B O, so if A O > B O, then the algorithm fails. Thus, a counterex- ample is multiplying a 1x1 matrix by a 1x3 matrix by a 3x2 matrix. (b, c) A counterexample is multiplying a 1x1 matrix by a 1x2 matrix by a 2x3 matrix.
10.31 The optimal binary search tree is the same one that would be obtained by a greedy stra- tegy: I O is at the root and has children and O and it O; a O and or O are leaves; the total cost is 2.14.
10.33 This theorem is from F. Yao’s paper, reference [58].
10.34 A recursive procedure is clearly called for; if there is an intermediate vertex, StopOver O on the path from s O to t O, then we want to print out the path from s O to StopOver O and then StopOver O to t O. We don’t want to print out StopOver O twice, however, so the procedure does not print out the first or last vertex on the path and reserves that for the driver.
/* Print the path between S and T, except do not print / / the first or last vertex. Print a trailing " to " only. */
void PrintPath1( TwoDArray Path, int S, int T ) { int StopOver = Path[ S ][ T ]; if( S != T && StopOver != 0 ) { PrintPath1( Path, S, StopOver ); printf( "%d to ", StopOver ); PrintPath1( Path, StopOver, T ); } }
/* Assume the existence of a Path of length at least 1 */
void PrintPath( TwoDArray Path, int S, int T ) { printf( "%d to ", S ); PrintPath1( Path, S, T ); printf( "%d", T ); NewLine( ); }
10.46 We place circles in order. Suppose we are trying to place circle P j O, of radius r P j O. If some
To see this, notice that the line connecting the centers has length r (^) i O + r P j O, and the difference in y O-coordinates of the centers is O|O r P j O − ri OO|O. The difference in x O-coordinates follows from the Pythagorean theorem.
To place circle P j O, we compute where it would be placed if it were tangent to each of the first P j O−1 circles, selecting the maximum value. If this value is less than r P j O, then we place circle P j O at x P j O. The running time is O O( N O^2 ).
10.47 Construct a minimum spanning tree T O of G O, pick any vertex in the graph, and then find a path in T O that goes through every edge exactly once in each direction. (This is done by a depth-first search; see Exercise 9.31.) This path has twice the cost of the minimum span- ning tree, but it is not a simple cycle. Make it a simple cycle, without increasing the total cost, by bypassing a vertex when it is seen a second time (except that if the start vertex is seen, close the cycle) and going to the next unseen vertex on the path, possibly bypassing several vertices in the process. The cost of this direct route cannot be larger than original because of the triangle inequality. If there were a tour of cost K O, then by removing one edge on the tour, we would have a minimum spanning tree of cost less than K O (assuming that edge weights are positive). Thus the minimum spanning tree is a lower bound on the optimal traveling salesman tour. This implies that the algorithm is within a factor of 2 of optimal.
10.48 If there are two players, then the problem is easy, so assume k O > 1. If the players are num- bered 1 through N O, then divide them into two groups: 1 through N O / 2 and N O / 2 + 1 though N O. On the i O th O^ day, for 1 ≤ i O ≤ N O / 2, player p O in the second group plays players (( p O + i O) mod O N O / 2) + 1 in the first group. Thus after N O / 2 days, everyone in group 1 has played everyone in group 2. In the last N O / 2 −1 days, recursively conduct round-robin tournaments for the two groups of players.
10.49 Divide the players into two groups of size OI N O / 2 OK and OH N O / 2 OJ, respectively, and recur- sively arrange the players in any order. Then merge the two lists (declare that px O > py O if x O has defeated y O, and py O > px O if y O has defeated x O − exactly one is possible) in linear time as is done in mergesort.
10.51 Divide and conquer algorithms (among others) can be used for both problems, but neither is trivial to implement. See the computational geometry references for more information.
10.52 (a) Use dynamic programming. Let Sk O= the best setting of words wk O, wk O+ 1 , ... wN O, Uk O= the ugliness of this setting, and l (^) k O= for this setting, (a pointer to) the word that starts the second line. To compute Sk O− 1 , try putting wk O− 1 , wk O, ..., wM O all on the first line for k O < M O and
i O= k O− 1
M wi O< L O. Compute the ugliness of each of these possibilities by, for each M O, comput-
ing the ugliness of setting the first line and adding Um O+ 1. Let M' O be the value of M O that yields the minimum ugliness. Then Uk O− 1 = this value, and lk O− 1 = M' O + 1. Compute values of U O and l O starting with the last word and working back to the first. The minimum ugliness of the paragraph is U O 1 ; the actual setting can be found by starting at l O 1 and following the pointers in l O since this will yield the first word on each line. (b) The running time is quadratic in the case where the number of words that can fit on a line is consistently Θ( N O). The space is linear to keep the arrays U O and l O. If the line length is restricted to some constant, then the running time is linear because only O O(1) words can go on a line. (c) Put as many words on a line as can fit. This clearly minimizes the number of lines, and hence the ugliness, as can be shown by a simple calculation.
10.53 An obvious O O( N O^2 ) solution to construct a graph with vertices 1, 2, ..., N O and place an edge ( v O, w O) in G O iff a (^) v O < aw O. This graph must be acyclic, thus its longest path can be found in time linear in the number of edges; the whole computation thus takes O O( N O^2 ) time. Let BEST O( k O) be the increasing subsequence of exactly k O elements that has the minimum last element. Let t O be the length of the maximum increasing subsequence. We show how to update BEST O( k O) as we scan the input array. Let LAST O( k O) be the last element in BEST O( k O). It is easy to show that if i O < P j O, LAST O( i O) < LAST O(P j O). When scanning aM O, find the largest k O such that LAST O( k O) < aM O. This scan takes O O(log t O) time because it can be performed by a binary search. If k O = t O, then xM O extends the longest subsequence, so increase t O, and set BEST O( t O) and LAST O( t O) (the new value of t O is the argument). If k O is 0 (that is, there is no k O), then xM O is the smallest element in the list so far, so set BEST O(1) and LAST O(1), appropriately. Otherwise, we extend BEST O( k O) with xM O, forming a new and improved sequence of length k O+1. Thus we adjust BEST O( k O+1) and LAST O( k O+1). Processing each element takes logarithmic time, so the total is O O( N Olog N O).
10.54 Let LCS O( A O, M O, B O, N O) be the longest common subsequence of A O 1 , A O 2 , ..., AM O and B O 1 , B O 2 , ..., BN O. If either M O or N O is zero, then the longest common subsequence is the empty string. If x (^) M O = yN O, then LCS O( A O, M O, B O, N O) = LCS O( A O, M O−1, B O, N O−1), AM O. Otherwise, LCS O( A O, M O, B O, N O) is either LCS O( A O, M O, B O, N O−1) or LCS O( A O, M O−1, B O, N O), whichever is longer. This yields a standard dynamic programming solution.
10.56 (a) A dynamic programming solution resolves part (a). Let FITS O( i O, s O) be 1 if a subset of the first i O items sums to exactly s O; FITS O( i O, 0) is always 1. Then FITS O( x O, t O) is 1 if either FITS O( x O − 1, t O − ax O) or FITS O( x O − 1, t O) is 1, and 0 otherwise. (b) This doesn’t show that P O = NP O because the size O of the problem is a function of N O and log K O. Only log K O bits are needed to represent K O; thus an O O( NK O) solution is exponential in the input size.