CISC 320 Algorithms and Advanced Programming, Spring 2001

Homework set #1 solution sketches

Handed out: March 6, 2001 Due date: March 20, 2001
  1. Textbook exercise 4.38 (heap construction)
    Answer part a with respect to the code in the text.

    Ans:
    ConstructHeap is tree recursive, first calling itself on left and right subtrees before doing fixHeap at a node. Any one chain of calls to constructHeap, however, is limited by the depth of the tree, about lg(n) for an n element heap. Also fixHeap is linear recursive, descending down at most to a leaf from a given node. Thus the number of activation frames pending at any one time is limited to a total of about lg(n). Final answer.

    To elaborate a bit, we can show the activation sequence for a heap with 4 levels:

    constructHeap(H)                       *
     constructHeap(LH)                     *
      constructHeap(LLH)
       constructHeap(LLLH)
       constructHeap(RLLH)
       fixHeap(LLH)
        fixHeap(XLLH), where X is L or R
      constructHeap(RLH)
       constructHeap(LRLH)
       constructHeap(RRLH)
       fixHeap(RLH)
        fixHeap(XRLH), where X is L or R
      fixHeap(LH)                          *
       fixHeap(XLH), where X is L or R     *
        fixHeap(YXLH), where Y is L or R   **
     constructHeap(RH)
      ...
    
    The activation frames at any one time are the latest one at each level of indentation. At the time of the ** call the * frames are active. The number of levels of indentation is about lg(n), specifically ceiling(lg(n)) + 1.

    Part b ans:

    fixHeap(H, K) // Outline
     while(true) do
      if (H is a leaf)
         insert ...
         return;
      else 
        Set ...
        ...
        if ...
         insert K in root(H);
         return;
        else
           insert root(largerSubHeap) in root(H)
           H = largerSubHeap; // and go to top
     endwhile
     return;
    

    Part c ans:
    FixHeapFast, BubbleUpHeap, and Promote get similar treatment

    Part d ans:

    constructHeap(H)
      for ( i = n/2; i > 0; --i)
        fixHeapFast(E, n, E[i], i, ceiling(lg(n-i)))
    

    Part e ans:
    FixHeapFast is called by constructHeap at every node except the leaves. FixHeapFast (as with fixHeap) requires comparisons of at most 2 times the depth of the tree at the node. The depth of the heap rooted at E[i] is about lg(n) - lg(i), because floor(lg(i)) is the number of steps i, parent of i, ... root. Thus the number of comparisons in constructHeap is no more than the sum from i=1 to n/2 of (lg(n) - lg(i)). This is O(n), as can be determined by any one of several methods.

    One way is to consider what happens as you double the number of nodes. Suppose W(n) has been figured out and we would like to understand W(2n). In effect the new heap has one additional row. Each of the about n/2 leaves (x) of the size n heap gets 2 children. The fixHeap cost at the n/2 internal nodes (Int) of the original heap is increased by 2 comparisons, because each fixHeap call from constructHeap has one more level down to process. The fix heap cost of 2 per node at the n/2 leaves (x) of the original heap is added as they now become internal nodes one level up from the bottom (y). Thus we have the recursion W(2n) = 2W(n) + 2(n/2). Apply master theorem.

                           Nodes
           .
          / \
         /   \             about
        / Int \             n/2
       /       \
      -----------
     x   x   x   x          n/2
    y y y y y y y y          n
    

  2. (a) Textbook exercise 5.7 (third largest)

    Part a ans:
    Use the tournament method for finding the largest. You build a heap of size about 2n with the data at the bottom and comparison winners copied up to parent positions. Put a flag with each parent position telling which side the element comes from. The will allow you to descend from the root (max element) finding all the elements that lost directly to the max without using any more comparisons. Copy these about lg(n) elements into another (smaller) heap. Associate each of them with level at which they lost to the max in the original heap. Find the max of that heap. It is the second largest. Go back to the original heap and find those which lost to the second largest. The associated level let's you do this without any more comparisons. Gather the about lg(n) elements that lost to the second largest or to the max but not to the second largest. Find the max of this group: it is the third largest overall. Comparisons: about n + 2lg(n).

    (b) In a heap of size 26, how many positions are possible locations of the third largest element? Draw the heap as a tree and mark the positions where the third largest might reside.

    Part b ans:

           
    level
    0                   m               
    1          s|t             s|t       
    2       t       t       t       t   
    3     x   x   x   x   x   x   x   x 
    4    x x x x x x x x x x x 
    
    The third could be in any position on the 2nd or third level. Anything lower has 3 or more known larger elements.

    (d) Extra credit contest: (I will report the results)

  3. Textbook exercise 6.9 (red-black depth)

    Ans:
    This sequence of inserts given to 320/red-black/dictMain will do it.

    i h 1 
    
    i d 2 
    i l 3  
    
    i b 4
    i f 5
    i h 6
    i m 7
    
    i a 8
    i c 9
    i e 10
    i g 11
    i i 12
    i k 13
    i m 14
    i o 15
    
    At the 13th insertion, "on the way down (altruistic)" splitting used by rbt.h splits the root trio (d,h,l) (again). The authors' "on the way up" splitting would not.

  4. Textbook exercise 11.18 (Boyer Moore tables and comparisons)

    Part a ans: Run the code.

    Part b ans: n - m + 1.


saunders@cis.udel.edu