[20] Question 1:
Please answer the following questions by circling either true or false.
 
 
1.
 
True False
 

 

C++ uses a special internal mechanism to allow the use of << and >> with streams; it is not possible for a programmer to use this mechanism with other classes.
 
2.
 
True False
 

 

A precondition on a function can document what inputs are legal to a function, but it can't prevent the program from attempting to call the function with illegal inputs.
 
3.
 
True False
 

 

Given an arbitrary binary tree, a postorder traversal of that tree will visit the nodes in the exact reverse order of a preorder traversal.
 
4.
 
True False
 

 

For a stack, "push" and "pop" cancel each other out: a push of any value followed by a pop leaves the stack in exactly the state it was in initially.
 
5.
 
True False
 

 

For a queue, "enqueue" and "dequeue" cancel each other out: an enqueue of any value followed by a dequeue leaves the queue in exactly the state it was in initially.
 
6.
 
True False
 

 

The "new" operator in C++ returns a fresh, statically-allocated instance of a class.
 
7.
 
True False
 

 

If a function f(n) is always less than another function g(n), then f(n) = O(g(n))
 
8.
 
True False
 
  Different binary search trees can have the same inorder traversal.
 
9.
 
True False
 
  Although binary searching a sorted array has logarithmic runtime on average, it can take as much as linear time in the worst case.
 
10.
 
True False
 
  If a class overloads the + operator, the compiler will check that the associated function really does perform an addition-like operation.
 
11.
 
True False
 
  Every binary tree with more than three nodes must have an interior node that is not the root.
 
12.
 
True False
 
  C++ references are a purely syntactic convenience that do not make the language inherently more powerful than C.
 
13.
 
True False
 
  Since a derived class does not have access to its base class's private data, instances of the derived class do not set aside space for the base class's data members.
 
14.
 
True False
 
  The C++ inheritance mechanism allows us to rewrite any recursive function non-recursively.
 
15.
 
True False
 
  Activation records are allocated in a special region of memory that is managed automatically by the language.
 
16.
 
True False
 
  According to the definition of the Set ADT, if I have a set of 10 integers, and I add an integer to the set, I will always end up with a set of 11 integers.
 
17.
 
True False
 
  assert( false ) at any point in a program will cause that program to immediately abort.
 
18.
 
True False
 
  It is impossible to write a binary search function for a sorted linked list of integers that runs in O(log n) time for a list of length n.
 
19.
 
True False
 
  The this pointer is a global variable in C++ programs that points to a single, statically-allocated object.
 
20.
 
True False
 
  The bool type with the values true and false, and the int type with the values 1 and 0 can both be used to represent boolean values, but 1 and 0 should be used when possible because it makes the program faster.
 

[12] Question 2:
Here is a C++ function that implements a new kind of searching algorithm:
 

int deluxeSearch( int data[], int size, int item )
{
    return deluxeSearchInRange( data, item, 0, size - 1 );
}

int deluxeSearchInRange( int data[], int item, int lo, int hi )
{
    if( lo hi ) {
        return -1;
    }

    int mid1 = lo + (hi-lo)/3;
    int mid2 = lo + 2 * (hi - lo)/3;
    if( item < data[ mid1 ] ) {
        return deluxeSearchInRange( data, item, lo, mid1 - 1 );
    } else if( item == data[ mid1 ] ) {
        return mid1;
    } else if( item data[ mid1 ] && item < data[ mid2 ] ) {
        return deluxeSearchInRange( data, item, mid1 + 1, mid2 - 1 );
    } else if( item == data[ mid2 ] ) {
        return mid2;
    } else {
        return deluxeSearchInRange( data, item, mid2 + 1, hi );
    }
}
Answer the following questions:
 
  1. In terms of the way it searches through a sorted array, is deluxe search more like linear search or binary search?

  2.  

     

  3. For an array of size n, what's the maximum number of times deluxeSearchInRange will make a recursive call to itself while searching?

  4.  

     
     
     

  5. Give a tight Big-O bound for deluxeSearch in terms of the size of the passed-in array.  Make the bound as simple as possible by removing any constant factors or lower-order terms.

  6.  

     

[8] Question 3:
You've been asked to design and build an ADT that manages information about a collection of students enrolled in a class.  When you sit down to start writing the C++ code, you realize that there are many unspecified details for this task!

Give two questions that you would like to ask about the specification of this ADT before you start programming.  For each question, write a sentence or two explaining why the answer to this question would affect your approach to the task
 

[14] Question 4:
Here is a portion of a program:
 

#include <iostream.h>

class Simple
{
public:
    virtual int goAhead();
};

int Simple::goAhead() {
    return 17;
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
int main( void )
{
    Simple *obj = getSimpleObject();
    cout << (obj-goAhead()) << endl;
    return 0;
}
This is obviously not a complete program, because it's missing at least the definition of the function getSimpleObject().  Surprisingly, when I compile and run the whole program, it prints out not 17, but 51!  It's possible to finish writing this program in such a way that it prints out 51.  Provide the rest of the program so that this happens.  You may not modify the code that's already written down; you should instead add a definition for the getSimpleObject function (and probably add some other code too).  You are also not permitted to make any use of cout in the code you add. (Hint: what kind of method is goAhead)?
 

[10] Question 5:
Suppose you are given the following definition of a Dir type:
 

enum Dir {
    NORTH,
    EAST,
    SOUTH,
    WEST
};
 
  1. Write a function printDir that takes a direction and prints (using cout) the textual representation of that direction.

  2.  

     
     
     
     
     
     
     
     
     
     
     
     
     

  3. A malicious programmer could potentially cause an error in your printDir function using a cast, as follows:
 


    for( int idx = 0; idx < 10; ++idx ) {
        Dir sneakyDir = (Dir)(idx);
        printDir( sneakyDir );
    }

Choose a graceful method of error handling for printDir so that this malicious code doesn't cause unpredictable behaviour in the program.  How would you rewrite printDir to use this error handling mechanism?
 
 

[12] Question 6:
 
  1. Draw the binary search tree that results from inserting the numbers 16, 11, 2, 19, 5, 29, 18, 24 (in that order) into an initially empty tree.

  2.  

     
     
     
     
     
     
     
     
     
     
     
     
     

  3. Write out the values in the tree from part (a) as they would be encountered in a preorder, inorder and postorder traversal of the tree

  4.  

     
     
     
     
     
     
     
     
     

  5. Now suppose I search the tree for the value 6, using the recursive method for finding an item in a binary search tree (the one that doesn't examine the whole tree).  Write down the nodes that I would look at while performing the search.

  6.  
[24] Question 7:
You and some friends decide to write a program to store the names of current movies along with their ratings, so that you can collectively decide what  movies to bet on for the academy awards.  You and your friends rate individual movies on an integer scale of 0 to 10.  A movie's overall rating is a floating-point number from 0.0 to 10.0, which is computed by taking the average of all the votes you and your friends have cast for that movie.

To store movie ratings, you decide to create a table-style ADT called MovieDict. An instance of the MovieDict ADT should be able to record votes, return the ratings for movies by name, and provide the name of the highest-rated movie.  Although the final version of the program will be used from a WWW turnin-like form, you are provided with the following sample client program to get an idea of how MovieDict will be used:
 

#include "moviedict.h"
int main( void )
{
    MovieDict dict;
    dict.vote( "Citizen Kane", 9 );   // Bob votes 9 on "Citizen Kane"
    dict.vote( "The Avengers", 1 );   // Fred votes 1 on "The Avengers"
    dict.vote( "Citizen Kane", 10 ); // Fred votes 10 on "Citizen Kane"
    dict.vote( "Fargo", 10 );         // Alice votes 10 on "Fargo"
    // Prints out 1.0, the average of all votes for "The Avengers"
    cout << dict.getRating( "The Avengers" ) << endl;
    // Prints out 9.5, the average of all votes for "Citizen Kane"
    cout << dict.getRating( "Citizen Kane" ) << endl;
    char buf[ 100 ];
    // Copies "Fargo" into the buffer buf, because it has
// the highest overall rating, 10.
    dict.findBest( buf );
cout << "The movie to bet on is " << buf << "." << endl;
    return 0;
}
You've already completed some of the design of the ADT.  You've decided to use a linked-list representation to store the dictionary entries.  You've even created a declaration for a Node struct (that goes into the header file "moviedict.h"), which the ADT will use to store information for each movie:
 
 
 
 
 
 
 
 
 
 

#ifndef __MOVIEDICT_H__
#define __MOVIEDICT_H__
 

const int MAX_NAME_LENGTH = 100;

struct Node
{
    char name[ MAX_NAME_LENGTH ]; // The name of this movie
    int sum_of_votes; // The sum of all votes cast so far
    int number_of_votes; // The number of votes cast, needed
// to compute the average

    Node *next; // Linked-list pointer
};

#endif // __MOVIEDICT_H__
 
 

  1. Complete the header file above by adding a declaration for the MovieDict class.  The methods that need to go into the class are precisely those that are implied by the sample client above.  The private data should be chosen to allow a linked-list representation based on the Node struct.  All the information you need to create the header file should be given above.  But if you need to make additional assumptions about the class in order to answer this question, simply state your assumptions below.

  2.  

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     

  3. Give the implementation of the getRating method of MovieDict.  You may find the function strcmp helpful.  strcmp takes two strings as arguments.  It returns 0 when the strings are equal and nonzero when they are unequal.  Your function should attempt to deal gracefully with the case of trying to get the rating of a movie that isn't in the database.

  4.  

     
     
     
     
     
     
     
     
     
     
     
     
     

  5. Suppose that somewhere in my client program, I have the following:

  6.     MovieDict m1;
        m1.vote( "Pi the Movie", 9 );
        // ... other stuff here
        MovieDict m2 = m1;

    What potential dynamic memory problem can arise by doing this assignment?
     
     

  7. What methods should I add to the MovieDict class to prevent it from potentially causing memory errors?

  8.  

     
     
     
     
     
     

 
 
 

[4] Bonus Question 1:
Give at least four of the metasyntactic variable names mentioned in lecture this quarter.
 
 
 
 

[10] Bonus Question 2:
Suppose that we redefine the nodes we use in binary search trees as follows:
 

struct FancyNode
{
    int data;

    FancyNode *parent;
    FancyNode *left;
    FancyNode *right;
};

In this representation, every node points to its left and right children, and also to its immediate parent (through the parent pointer).  It turns out that given a pointer to a FancyNode which is the root of a binary search tree, it's possible to do an inorder traversal of the tree with O(1) additional space (that is, the amount of extra memory you use is constant: no recursion, no stacks, no extra dynamic memory of any kind!)  Write a function cheapInOrder( FancyNode *root ) that does this.