2010_Fall_Exam_1_Key

advertisement
Fall 2010 Data Structures
Midterm Exam
Name _____________Key_________________________
Instructions
Leave the test on your desk with this page facing up until you are told to start.
You will then have one hour to complete the test.
Please turn off your cell phone.
Be sure your name is on the test.
This is an open book test. You may use your computer, books, notes, etc. You
may not communicate with anyone during the test by any means.
You may hand in the test and leave at any time prior to the end time. If you leave
the room (for any reason), you cannot return and continue the test.
No questions will be answered during the test. If you don’t understand a
question on the exam, or you think there is an error in the question statement,
make the best assumptions you can and answer the question on that basis. You
may write a note with your answer explaining your assumptions.
There are several multiple choice questions. Some say to select the best choice;
others say to select all choices that are true. Pay close attention to these
instructions, which appear below the choices. For “best choice” select only one
alternative. For “all that are true” any number of choices, including none and all,
might be true. Circle the letter beside a choice in order to select it.
Some questions will probably be more difficult than others. But sure to answer
all of the easy questions before spending too much time on a difficult one.
All questions are worth four points unless specified otherwise, for a total of 100.
You should have a source code listing of the solution for Project 3, Cats_in_Tree,
stapled separately for convenient reference. The code to make queries about
cats in the tree has been removed from main.cpp. The first 14 questions refer to
that program. In answering these questions, you may make use of any existing
code, but you should not modify the existing code.
1. Write a method that returns the number of elements in the tree. It should
implement following declaration in the BST class definition. (10 points)
int count();
// Return number of items in the tree
The new method could be called from main with a statement such as the
following:
int cat_count = myCats->count();
cout << "There are " << cat_count << " cats in the tree\n";
Here is a sample run.
In the space below, write code to be added to genBST4.h to implement the
method.
template<class T>
int BST<T>::count()
{
return determine_positions(root, 0);
}
If you didn’t notice that the determine_positions method returns the count, you
could write this method from scratch. Probably the easiest way to do it is to do a
breadth first search and keep track of how many nodes you visit.
(See next page.)
template<class T>
int BST<T>::count()
{
int ct = 0;
Queue<BSTNode<T>*> queue;
BSTNode<T> *p = root;
if (p != 0)
{
queue.enqueue(p);
while (!queue.empty())
{
p = queue.dequeue();
++ct;
if (p->left != 0)
{
queue.enqueue(p->left);
}
if (p->right != 0)
{
queue.enqueue(p->right);
}
}
}
return ct;
}
Note that this function is almost identical to BST<T>::breadthFirst().
2. As the BST template is currently written, there is no way to search for a cat by
name. In order to find “Fluffy” in the tree, we have to instantiate a Cat with the
name Fluffy and search for that cat object.
A naive programmer might be tempted to add a new method
T* search(string name) const;
to the BST so that he can search for a Cat by name. For example:
Cat* c = myCats->search(“Fluffy”);
What’s wrong with this idea?
It only works for classes that define operator==(string&), or provide a type
conversion from string.
Also OK: Returns a pointer. (Not the problem that I had in mind, but it is a valid
answer to the question.)
3. As an alternative to the above, the programmer could use the existing search
function and simply create a new Cat object with the desired name and search
for that cat.
Cat* c = myCats->search(*new Cat("Fluffy") );
if (c != 0)
{
c->display();
}
This idea will work, as shown by the output above, but it does have a flaw.
What is the flaw?
It has a memory leak. The argument to search, *new Cat(“xxx”) creates a Cat
object but does not delete it and does not store the pointer.
Also OK: Returns a pointer.
Also OK: No output if cat is not found in the tree.
4. Rewrite the code show above to display the info about Fluffy without the defect
in the that code.
To avoid the memory leak, the program should delete each Cat that it creates to
use as the argument to search.
Cat* c1 = new Cat("Fluffy");
const Cat* c2 = myCats->search(*c1);
if (c2 != 0)
{
c2->display();
}
delete c1;
Other correct solutions are possible.
5. The search function in the current BST template has a serious defect in that it
returns a pointer to the “key” member of the node that it finds. Client code can
use this pointer to modify the contents of the BST, as in the example shown
below:
Cat* c = myCats->search(*new Cat("Fluffy") );
c->display();
*c = *new Cat("Bogus");
myCats->display_v(cout, 8);
What principle of object oriented programming does this violate?
Encapsulation
6. We can mitigate the problem described above by changing the search method
to return a const pointer. Then any code that tries to use the pointer returned by
search to modify the tree will not compile. But there would still be a potential
problem. Client code could retain the const pointer until sometime later when the
node that it points to has been deleted.
const Cat* c = myCats->search(*new Cat("Fluffy") );
c->display();
//*c = *new Cat("Bogus");
//myCats->display_v(cout, 8);
myCats->delete_node(*c);
myCats->display_v(cout, 8);
c->display();
Using the pointer will then cause the program to blow up.
How could you modify the search method so that it is not subject to even this
problem? (Just describe what you would do. You don’t need to show actual
code.)
Modify the search function to return an object rather than a pointer.
7. From time to time a need will arise to determine facts about the cats in the
tree. For example, we might want to know which is the fattest cat, or the oldest
cat, or the youngest cat, or the cat with the longest name. We could add new
methods to the BST template to answer these questions. But that would not be a
good solution. First of all, it would tend to specialize the BST for cats, moving it
away from being a general purpose container template. And every new question
would require a new method, leading to code bloat in the template and making it
less desirable as a reusable component.
How could you modify the template so that clients could write their own functions,
outside the template, to answer these questions and others? (Just describe what
you would do. You don’t need to show actual code.) (10 points)
Modify the traverse methods to take a function pointer as a second parameter.
The caller can then provide a pointer to a function to do whatever is needed for
each node in the tree.
For 10 points extra credit, describe how clients could answer such questions
even without modifying the existing template. (This is something that we have
not discussed in class, except very briefly.)
Create a derived class and override the visit method to do whatever is needed.
8. Suppose you have 1000 cats to keep track of and you add a Cat object to the
tree for each of them in such a way that the tree stays balanced. What will be
the maximum number of comparisons that will have be done by the search
method to locate any cat in the tree?
10
9. Still assuming that you have 1000 cats in the tree, suppose you search for a
cat that is not in the tree. What will be the maximum number of comparisons that
have to be done by the search method in order to determine that the cat is not
present?
10
10. If you had used a Linked List to hold your cat info rather than a Binary Search
Tree, what would be the maximum number of comparisons necessary to find the
information for a cat that is present?
1000
11. Still assuming that you used a list, what would be the maximum number of
comparisons necessary to determine that a given cat is not present?
1000
12. Class Cat has a display method and a << operator, defined as follows in
Cat.cpp (Lines 15 – 25)
void Cat::display() const
{
cout << name << " dob: " << date_of_birth
<< " weight: " << weight << endl;
}
ostream& operator<<(ostream& os, const Cat & c)
{
os << c.get_name();
return os;
}
Why does operator<< use the accessor function, “get_name()”, while the display
method refers directly to the member variable “name” ?
display() is a member of class Cat. So it has direct access to the private
members of the class. operator<<() is not a member (or a friend) so it cannot
access private members directly. It can only use the public accessor methods.
13. Either of these methods can be used to output information about a cat to the
screen. What can the << operator do that the display method cannot?
It can write its output to a file, as well as to the screen.
Also OK: Can be cascaded (or chained)
14. The display method outputs the cat’s date of birth using the << operator. As
the program is currently written, the date of birth will be shown in the usual
American format, mm/dd/yyyy. Suppose you want to show the date in the
dd/mm/yyyy format that is more common in Europe. What single line of code
would you change? (File name and line number)
File Date.cpp, line 26.
The remaining questions are independent of the Cats_in_Tree program.
15. Which of the following operations would normally be provided in an Abstract
Data Type for a List?
a. Get the first element of the list.
b. Get the element at a specified position in the list.
c. Insert an element at a specified position.
d Delete the element at a specified position.
Select all choices that are true.
16. Which of the following operations would normally be provided in an Abstract
Data Type for a Queue?
a. Get the first (oldest) element of the queue.
b. Get the element at a specified position in the queue.
c. Insert an element at a specified position.
d. Delete the element at a specified position.
Select all choices that are true.
17. Which of the following operations would normally be provided in an Abstract
Data Type for a Stack?
a. Get the top element of the stack.
b. Get the element at a specified position in the stack.
c. Insert an element at a specified position.
d. Delete the element at a specified position.
Select all choices that are true.
18. What are some advantages and disadvantages of a doubly linked list relative
to a singly linked list?
Advantages:
Can traverse from end to beginning as well as beginning to end.
Accessing the last element is easier.
Disadvantages:
Uses more memory.
Takes more time to insert and delete, due to the requirement to update more
pointers
19. We have looked at two implementations of a Stack Abstract Data Type. One
used an array to hold the stack’s data. The other used a linked list. Using a
linked list to implement a stack is an example of
a. an adapter.
b. inheritance.
c. polymorphism.
d. function overloading.
Select the best choice.
20. In addition to ease of implementation, what is a significant advantage of using
a linked list rather than an array to implement a stack?
The stack can grow indefinitely, limited only by the amount of memory available.
21. In one class we looked at an abstract data type for a set of queues with a
fixed number of elements that move around among the queues. The public
interface for this ADT was different from that for a traditional Queue ADT. The
only public method that moves elements around within the queues is the
“requeue” method.
void requeue (int from_queue_id, int to_queue_id);
What does this method do?
It moves the element at the front of the “from” queue to the end of the “to” queue.
22. We have seen how to use a list to implement a queue. What about using a
queue to implement a list? Would this make sense? Why or why not?
No. Because a queue does not provide the ability to insert and delete elements
in the middle of the queue, which is required for a list.
Download