Test 1, CSCI 385, Fall 2005

  1. [5 pts each (25 total)] Describe what each routine does (at a high level). Derive and state the performance for each. State what value you use for "n".
    I decided to grade each problem as follows
        1  point for the description
        2  points for performance derivation
        1  point for correctly stating big O performance
        1  point for correctly identifying what n is.
    
    Note, I described in class what I meant by high level description.  
    This was somewhat fuzzy, but it was stated that it was NOT a line
    by line description of the routine.
    
    1. int routineA(int base, int exponent){
      
          int value = 1;
          int i;
      
          for(i=1;i<=exponent;i++) {
              value *=base;
          }
          return value;
      }
      
      This routine evaluates baseexponent
      Time = ∑i=1exponent 1 = 1+1+...+1 (n times) = n
      The algorithm is O(n) where n is the exponent.
      
      	

    2. int routineB(int base, int exponent) {
      
          if (exponent ==  0) {
              return 1;
          } else {
             return base * routineB(base, exponent-1);
          }
      }
      
      This routine evaluates baseexponent
      T(0) = 1
      T(n) = T(n-1) + c                  T(n-1) = T(n-1-1) + c = T(n-2)+c
           = T(n-2) + c + c
           = T(n-2) + 2c
        at step i
      T(n) = T(n-i) + ic
        let i = n
      T(n) = T(n-n) + nc
           = T(0) + nc
           = 1 + nc  which is O(n)
      The algorithm is O(n) where n is the exponent.
      
      
      
      Notice:
          The best case and the worst case are the same for this algorithm.
          It is based on the exponent, the algorithm is O(n) if n is big or small.
      
      	

    3. double routineC(double coeffs[], int size, double x) {
      
          int i;
          double y=0;
      
          for(i=0;i<=size;i++) {
              y += coeffs[i] * pow(x,i);
          }
      }
      
      
      This routine will evaluate a polynomial
          P(x) = cnxn+cn-1xn-1...+c1x+c0
      
      n in this case is the size of the array of coefficients,
          or the degree of the polynomial
      
      The inner loop evaluates the power function (see the two previous exercises)
      So the performance will be
         T = 0 + 1 + 2 + 3 + 4 + ... + n
           = ∑i=0n i
           = n(n+1)/2 
      Which is O(n2)                               
      
      
      This is a tricky problem, and easy to assume it is O(n).  However, having
      just worked through the power function above, you should have seen this.
      
      Furthermore, question 5 refers you back to this problem, and gives a clue.
      you should have at least noted this as you read through the test the
      first time.
      
      The analysis of this problem is the same as the one we did for deleting
      an item from an arbitrary position in an array.
      
      I did fail to return a value here, but that does not change the performance 
      of the algorithm.
      
      	

    4. void routineD(int ary1[], int ary2[], int size) {
      

      int i,j; for(i=0;i<size;i++) { ary2[j] = 1; for(j=0;j<5;j++) { ary2[i] *= ary1[i]; } } } This routine calculates n5 for each element in the first array and stores it in the second array. n is the size of the array. Notice the inner loop is constant. (Big but constant) So the performance is T = c + c + c + ... + c (n times) = ∑i=1nc = cn Which is O(n) This is exactly Stan's question during the review. I had an error on the 2nd line of the code, but again the performance did not depend on this error.

    5. void routineE(int ary[], int size) {
      
        // findmin finds the position of the minimum element in the array 
        //   between (and including) the two endpoints passed)
        //   this is an O(end-start) routine.
          int i, max;
          for(i=0;i<size-1;i++) {
              max = findmin(ary,i, size-1) 
      	swap(ary[max],ary[i])
          }
      }
      
      This is selection sort.
      n is the size of the array.
      T(n) = n-1 + n-2 + n-3 + ... + 2
           = ∑i=2n-1 i
           = n(n-1)/2 - 1
           which is O(n2).
      
      	

      Please Continue on the Other Side.

  2. [15 pts] Divide and conquer.
    1. [2 pts] Describe the divide and conquer design principle.
      	  
      By dividing the problem into smaller parts, it is easier to solve
      the sub-parts.
      	  
      	  
    2. [3 pts] State the steps that are common to divide and conquer algorithms.
      
      divide the problem into sub-problems 
      conquer, or solve the sub-problems 
      combine, or reassemble the answer 
      
      
    3. Give an example of a divide and conquer algorithm.
      1. [2 pts] Name and describe the algorithm at a high level.
        
        Binary search.
        
        Check for an item at the middle of a sorted array
        If it is not there check the half of the array 
        where the item  would be.
        
        
      2. [3 pts] Give pseudo code for your algorithm.
        
        bool binarySearch(array, element, start, stop)
        
        1. if (start > stop)
        2. return false
        3. mid = (start+stop)/2
        4. if array[mid] = element
        5. return true
        6. else if array[mid] < element
        7. return binarySearch(array, element, mid+1, stop)
        8. else
        9. return binarySearch(array, element, start, mid-1)
    4. [3 pts] Identify the divide and conquer steps in your algorithm. If your algorithm does not required one of the steps, state this explicitly.
      
      Line 3 is the divide step
      Lines 7 and 9 are the conquer steps
      The return in 7 and 9 are the combine
      
      
    5. [2 pts] Derive and state the performance of your algorithm.
      
      T(n) = T(n/2) + c           T(n/2) = T(n/2/2) + c = T(n/22)+c
      T(n) = T(n/22) + c + c
           = T(n/22) + 2c
      at step i
      T(n) = T(n/2i) + ic
      assume n = 2k, lg(n) = k
      T(n) = T(n/sk) + kc
           = T(n/n) + kc
           = 1 + kc
           = 1 + c lg (n)
           which is O(lg(n))
      
      
      Other answers are acceptable here, but why do anything more complex?
      
      

  3. [30 pts] Arrays
    1. [10 pts] Describe the identifying characteristics of arrays. Include range, operations, and performance expectations.
      
      2 points
      An array is a collection of homogeneous objects characterized by 
      constant time random access.
      
      8 points
      Operations:
          change the value of an element      O(1)
          extract the value of an element     O(1)
          create the array                    O(1)
          destroy the array                   O(1)
          iterate over the array              O(n)
          initialize the array to a set value O(n)
      
      
    2. [5 pts] Describe the difference between compile time static, run time static, and dynamic arrays.
      
           A compile time static array  has memory allocated at 
              compile time and the size is never changed.
      
      	ex: int x[5];
      
          A run time static array has memory allocated once 
              during run time, and the size is never changed.
      
      	ex: int * x;
      
              x = new int[size];	
      
         A dynamic array has memory allocated at run time, but this may be changed
             later in the program as memory is needed.
      
      
      
    3. [5 pts] Describe the C++ STL container class vector.
      
      The C++ STL vector class is an implementation of a dynamic array.
      Elements may be added via the push_back routine.
      Elements may be deleted via the pop_back routine.
      Other normal array operations are supported.
      
      
    4. [10 pts] Describe the difference between inserting at the end of a dynamic array and at an arbitrary position within a dynamic array. Include a discussion algorithms to perform these actions and performance of these algorithms.
      
      Both of these operations may involve reallocating and copying data elements
      in the array.  Assume in both cases, that memory is reallocated only when the
      array becomes full, and further assume that the amount of memory is doubled
      when this occurs.
      
      dupArray(array, size) 
      
      1. tmp = new array twice the size of array
      2. for i=0, i<size, i++
      3. tmp[i] = array[i]
      4. delete array
      5. array = tmp
      6. maxsize = 2*size
      This is an O(n) algorithm from line 2. Inserting at the end of a dynamic array will be a constant time operation as the item is inserted only at the end of the array, and no other data need be copied. push_back(array, e)
      1. if size == maxsize
      2. dupArray(array, size)
      3. array[size] = e
      4. size ++
      Inserting into an arbitrary position will be at worst O(n) when we are inserting at the beginning of the array, as all data will need to be copied down one position. At best it will be constant, when the item is inserted at the end, and on average it will be T = 1/n * ∑i=0ni = 1/n * n(n+1)/2 = (n+1)/2 which is O(n) insert(array, e, pos)
      1. if size == maxsize
      2. dupArray(array, size)
      3. for i=size, i > pos, i++
      4. array[i] = array[i-1]
      5. array[pos] = e
      As we have seen in class, using dupArray will have O(1) performance in the average case.

  4. [20 pts] Sorting.
    1. [5 pts] Describe the purpose of a sorting algorithm.
       
      
      Place a collection of elements in order.
      
      
    2. Select one sorting algorithm not already covered in this test.
      
      Many answers are acceptable.
      Selection sort may not be used.
      
      
      1. [1 pt] Name this sort.
      2. [2 pts] Describe at a high level what this sort does.
      3. [3 pts] Give a pseudo code algorithm for this sort.
      4. [3 pts] What is the worst case performance for this algorithm? Give an example of a data set that will produce this performance.
      5. [3 pts] What is the best case performance for this algorithm? Give an example of a data set that will produce this performance.
      6. [3 pts] What is the average case performance for this algorithm?

    
    You should do this for 10 points extra credit on the test.
    
        
  5. [10 pts] Horner's Algorithm can be used to evaluate an polynomial at a point in O(n) time.

    Given: P(x) = cnxn+cn-1xn-1...+c1x+c0

    Horner's algorithm says:

    P(x) = c0+x*(c1+x*(c2+x*( ...+x(cn-1+x*cn))...))

    1. [3 pts] Express P(x) = 4x3 + 7x3+4x2+5x + 4 using Horner's algorithm.
    2. [3 pts] Give a pseudo code implementation of Horner's algorithm.
    3. [3 pts] Derive and state the performance of your implementation of Horner's algorithm.
    4. [1 pt] Go back and redo 1C. State the performance Difference between Horner's, and the algorithm in 1C.