CMSC 341 Stacks and Queues 1252022 1 Stack























- Slides: 23
CMSC 341 Stacks and Queues 1/25/2022 1
Stack ADT Restricted List only add to top only remove from top Examples pile of trays partial results local state 1/25/2022 2
Relation to Previous List Using inheritance: Stack Is-A List Need to pay special intention that List operations are properly performed Using aggregation: Stack Has-A List 1/25/2022 3
Stack. H #include “Linked. List. H” template <class Object> class Stack { public: Stack(); Stack(const Stack &coll); ~Stack(); bool is. Empty() const; bool is. Full() const; const Object &top() const; void make. Empty(); void pop(); void push(const Object &x); Object top. And. Pop(); const Stack &operator=(const Stack &stk); 1/25/2022 4
Stack. H (cont) protected: const List<Object> &get. List() const; void set. List(List<Object> &lst); List. Itr<Object> &get. Zeroth(); private: List<Object> _the. List; List. Itr<Object> _zeroth; }; 1/25/2022 5
Stack. C template <class Object> Stack<Object>: : Stack(){ _zeroth = get. List(). zeroth(); } template <class Object> Stack<Object>: : Stack(const Stack &stk) { _the. List = stk. get. List(); _zeroth = get. List(). zeroth(); } template <class Object> Stack<Object>: : ~Stack() {} template <class Object> bool Stack<Object>: : is. Empty() const{ return get. List(). is. Empty(); } 1/25/2022 6
Stack. C (cont) template <class Object> bool Stack<Object>: : is. Full()const{ return false; } template <class Object> const Object & Stack<Object>: : top() const{ if (is. Empty()) throw Stack. Exception(“top on empty stack”); return get. List(). first(). retrieve(); } template <class Object> void Stack<Object>: : make. Empty () { get. List(). make. Empty(); } 1/25/2022 7
Stack. C (cont) template <class Object> void Stack<Object>: : pop() { if (is. Empty()) throw Stack. Exception(“pop on empty stack”); get. List(). remove(top()); } template <class Object> void Stack<Object>: : push(const Object &x) { get. List(). insert(x, get. Zeroth()); } template <class Object> Object Stack<Object>: : top. And. Pop () { if (is. Empty()) throw Stack. Exception(“top. And. Pop on empty stack”); Object tmp = top(); pop(); return tmp; 1/25/2022 } 8
Stack. C (cont) template <class Object> const Stack<Object> &Stack<Object>: : operator=(const Stack &stk) { if (this != &stk){ set. List(stk. get. List()); set. Zeroth(get. List(). zeroth()); } return *this; } template <class Object> const List<Object> &Stack<Object>: : get. List() { return _the. List; } template <class Object> List. Itr<Object> &Stack<Object>: : get. Zeroth () { return _zeroth; } 1/25/2022 9
Stack. Exception. H class Stack. Exception { public: Stack. Exception(); // Message is the empty string Stack. Exception(const string & error. Msg); Stack. Exception(const Stack. Exception & ce); ~Stack. Exception(); const Stack. Exception & operator=(const Stack. Exception & ce); const string & error. Msg() const; // Accessor for msg private: string _msg; }; 1/25/2022 10
Stack. Exception. C Stack. Exception: : Stack. Exception(){} Stack. Exception: : Stack. Exception(const string & error. Msg){ _msg = error. Msg; } Stack. Exception: : Stack. Exception(const Stack. Exception &ce){ _msg = ce. error. Msg(); } Stack. Exception: : ~Stack. Exception(){} 1/25/2022 11
Stack. Exception. C (cont) const Stack. Exception & Stack. Exception: : operator=(const Stack. Exception & ce) { if (this == &ce) return *this; // don't assign to itself _msg = ce. error. Msg(); return *this; } const string & Stack. Exception: : error. Msg() const { return _msg; } 1/25/2022 12
Test. Stack. C int main (){ Stack<int> stk; stk. push(1); stk. push(2); print. Stack(stk); Stack<int> otherstk; otherstk = stk; print. Stack(otherstk); cout << stk. top. And. Pop() << endl; 1/25/2022 13
Test. Stack. C (cont) print. Stack(stk); print. Stack(otherstk); try { stk. pop(); } catch (Stack. Exception & e){ cout << e. error. Msg() << endl; } } 1/25/2022 14
Test. Stack_aux. C template <class Object> void print. Stack( Stack<Object> & the. Stack ){ Stack<Object> tmp; if( the. Stack. is. Empty( ) ){ cout << "Empty stack" << endl; return; } while (the. Stack. is. Empty() == false) { Object top. Obj = the. Stack. top(); cout << top. Obj; tmp. push(top. Obj); // save on other stack the. Stack. pop(); if (the. Stack. is. Empty() == false) cout << ", "; } cout << endl; 1/25/2022 15
Test. Stack_aux. C while (tmp. is. Empty() == false) { Object top. Obj = tmp. top(); the. Stack. push(top. Obj); tmp. pop(); } } 1/25/2022 16
Queue ADT Restricted List only add to end only remove from front Examples line waiting for service jobs waiting to print 1/25/2022 17
Queue. H template <class Object> class Queue { public: explicit Queue(int capacity=10); bool is. Empty() const; bool is. Full() const; const Object &get. Front() const; void make. Empty(); Object dequeue(); void enqueue (const Object & x); private: vector<Object> the. Array; int current. Size; int front; int back; void increment (int &x); 1}/25/2022 18
Queue. C template <class Object> Queue<Object>: : Queue( int capacity ) : the. Array( capacity ) { make. Empty( ); } template <class Object> void Queue<Object>: : make. Empty( ) { current. Size = 0; front = 0; back = -1; } 1/25/2022 19
Queue. C (cont’d) template <class Object> void Queue<Object>: : enqueue(const Object &x){ if (is. Full()) throw Overflow(); increment (back); the. Array[back] = x; current. Size++; } template <class Object> void Queue<Object>: : increment(int &x) { if (++x == the. Array. size()) x = 0; } 1/25/2022 20
Queue. C (cont) template <class Object> Object Queue<Object>: : dequeue() { if (is. Empty()) throw Underflow(); current. Size--; Object front. Item = the. Array[front]; increment(front); return front. Item; } 1/25/2022 21
the. Array 1/25/2022 22
The Double-Ended Queue ADT The double ended queue is referred to as a Deque (rhymes with “check”) Restricted List add to the end remove from the end add to the front remove from the front Stacks and Queues are often implemented using a deque 1/25/2022 23