Saint Louis University |
Computer Science 180
|
Dept. of Math & Computer Science |
Topic: Stacks and Queues
Related Reading: Ch. 5, 6
Due:
Tuesday, 27 March 2007, 2:10pm
Please make sure you adhere to the policies on academic integrity.
Note: Problems A and B should be relatively straightforward if you are careful. Problem C is quite challenging, but a great exercise.
Assume that we have an initially empty stack, S, of integers. Fill in the following table (we have completed the first two rows), showing the output returned by each method call and the internal state of the stack after that point in time.
Operation | Output | S (bottom, ..., top) |
S.push(7) | - | (7) |
S.push(10) | - | (7, 10) |
S.pop() | ||
S.top() | ||
S.push(3) | ||
S.push(5) | ||
S.pop() | ||
S.empty() | ||
S.size() | ||
S.top() | ||
S.push(8) | ||
S.pop() | ||
S.pop() |
Assume that we have an initially empty queue, Q, of integers. Fill in the following table (we have completed the first two rows), showing the output returned by each method call and the internal state of the queue after that point in time.
Operation |
Output |
Q (front, ..., back) |
Q.push(10) | - | (10) |
Q.push(4) | - | (10, 4) |
Q.size() | ||
Q.front() | ||
Q.push(6) | ||
Q.pop() | ||
Q.push(3) | ||
Q.pop() | ||
Q.front() | ||
Q.pop() | ||
Q.push(7) | ||
Q.front() |
Chapters 5 and 6 in our book demonstrate the concept of an Adapter Class (see page 326). This is when you implement a given class based on the internal use of some other existing class. For example the code of Listings 5.1 with 5.5 shows how a stack could be implemented publically, while really using a single vector as the only instance variable.
For this problem, we want you to show how you could implement the queue class using nothing other than two stack instances. You may not declare any other attributes (though you are welcome to declare local variables within your method bodies).
For concreteness, we ask that you model your answer to this problem in C++ syntax, using the following framework (essentially taken from Listing 6.1) as the basis.
#include < stack > template <typename Item_Type> class queue { public: void push(const Item_Type& item) { } Item_Type& front() { } // for simplicity, we'll ignore the const version of front() void pop() { } bool empty() const { } size_t size() const { } private: // Do not use any data members other than the following two stacks std::stack<Item_Type> S1; std::stack<Item_Type> S2; }
To be successfully, you will need to keep straight your role as the implementor of a queue, yet also your role as a client for the stack.
To get you going, a natural implementation for the queue.size() method in this setting might be:
size_t size() const { return (S1.size() + S2.size()); }since we presume that all elements of the queue must be stored, and S1 and S2 are your only means of storage. (of course, if you decide to store an element in both stacks for some reason, you may have to adjust this size() implementation)
If you understand the goal, it is now time to think about how to solve the problem. Remember, anytime pop() is called on the queue, you must behave with a "first-in, first-out" principle. Make sure your code works for any sequence of push(), pop(), and front() operations.
As a dual to Problem C, demonstrate an adapter pattern which would implement a stack interface using a single queue as the only instance variable.