740 likes | 911 Views
Stacks. Chapter 8. Objectives. In this chapter, you will: Learn about stacks Examine various stack operations Learn how to implement a stack as an array Learn how to implement a stack as a linked list Discover stack applications Learn how to use a stack to remove recursion. Stacks.
E N D
Stacks Chapter 8
Objectives In this chapter, you will: • Learn about stacks • Examine various stack operations • Learn how to implement a stack as an array • Learn how to implement a stack as a linked list • Discover stack applications • Learn how to use a stack to remove recursion C++ Programming: Program Design Including Data Structures, Fifth Edition
Stacks • Stack: list of homogenous elements • Addition and deletion occur only at one end, called the top of the stack • Example: in a cafeteria, the second tray can be removed only if first tray has been removed • Last in first out (LIFO) data structure • Operations: • Push: to add an element onto the stack • Pop: to remove an element from the stack
Stacks • Linear list. • One end is called top. • Other end is called bottom. • Additions to and removals from the top end only. top bottom
top F top E E D D C C B B bottom bottom A A Stack Of Cups • Add a cup to the stack. • Remove a cup from new stack. • A stack is a LIFO list.
The Abstract Class stack template<class T> class stack { public: virtual ~stack() {} virtual bool empty() const = 0; virtual int size() const = 0; virtual T& top() = 0; virtualvoid pop() = 0; virtual void push(const T& theElement) = 0; };
Derive From A Linear List Class • Class arrayList • Class chain
a b c d e 0 1 2 3 4 5 6 Derive From arrayList • stack top is either left end or right end of linear list • empty() =>arrayList::empty() • size() =>arrayList::size() • top() => get(0) orget(size() - 1)
a b c d e 0 1 2 3 4 5 6 Derive From arrayList • when top is left end of linear list • push(theElement) => insert(0, theElement) • pop() => erase(0) • use left end of list as top of stack
a b c d e 0 1 2 3 4 5 6 Derive From arrayList • when top is right end of linear list • push(theElement) => insert(size(), theElement) • pop() => erase(size()-1) • use right end of list as top of stack
firstNode NULL a b c d e Derive From Chain • stack top is either left end or right end of linear list • empty() => chain::empty() • size() => chain::size()
firstNode NULL a b c d e Derive From Chain • when top is left end of linear list • top() => get(0) • push(theElement) => insert(0, theElement) • pop() => erase(0)
firstNode null a b c d e Derive From Chain • when top is right end of linear list • top() => get(size() - 1) • push(theElement) => insert(size(), theElement) • pop() => erase(size()-1) • use left end of list as top of stack
Derive From arrayList template<class T> classderivedArrayStack : privatearrayList<T>, public stack<T> { public: // code for stack methods comes here };
Constructor derivedArrayStack(int initialCapacity = 10) : arrayList<T> (initialCapacity) {}
a b c d e 0 1 2 3 4 5 6 empty() And size() bool empty() const {returnarrayList<T>::empty();} int size() const {returnarrayList<T>::size();}
a b c d e 0 1 2 3 4 5 6 top() T& top() { if (arrayList<T>::empty()) throwstackEmpty(); return get(arrayList<T>::size() - 1); }
a b c d e 0 1 2 3 4 5 6 push(theElement) void push(const T& theElement) {insert(arrayList<T>::size(), theElement);}
a b c d e 0 1 2 3 4 5 6 pop() void pop() { if (arrayList<T>::empty()) throwstackEmpty(); erase(arrayList<T>::size() - 1); }
template<class T> class derivedArrayStack : private arrayList<T>,public stack<T> { public: derivedArrayStack(intinitialCapacity = 10) :arrayList<T>(initialCapacity) {} bool empty() const {return arrayList<T>::empty();} int size() const {return arrayList<T>::size();} T& top() { if (arrayList<T>::empty()) throw stackEmpty(); return get(arrayList<T>::size() - 1); } void pop() { if (arrayList<T>::empty()) throw stackEmpty(); erase(arrayList<T>::size() - 1); } void push(const T& theElement) {insert(arrayList<T>::size(), theElement);} };
Evaluation • Merits of deriving from arrayList • Code for derived class is quite simple and easy to develop. • Code is expected to require little debugging. • Code for other stack implementations such as a linked implementation are easily obtained. • Just replace private arrayList<T> with private chain<T> • For efficiency reasons we must also make changes to use the left end of the list as the stack top rather than the right end.
Code From Scratch • Use a 1D array stack whose data type is T. • same as using array element in arrayList • Use an intvariable stackTop. • Stack elements are in stack[0:stackTop]. • Top element is in stack[stackTop]. • Bottom element is in stack[0]. • Stack is empty iff stackTop = -1. • Number of elements in stack is stackTop + 1.
Code From Scratch templateclass<T> class arrayStack : public stack<T> { public: // public methods come here private: int stackTop; // current top of stack int arrayLength; // stack capacity T *stack; // element array };
Constructor template<class T> arrayStack<T>::arrayStack(int initialCapacity) {// Constructor. if (initialCapacity < 1) {// code to throw an exception comes here } arrayLength = initialCapacity; stack = new T[arrayLength]; stackTop = -1; }
top a b c d e 0 1 2 3 4 push(…) template<class T> voidarrayStack<T>::push(const T& theElement) {// Add theElement to stack. if (stackTop == arrayLength - 1) {// code to double capacity coms here } // add at stack top stack[++stackTop] = theElement; }
top a b c d e 0 1 2 3 4 pop() void pop() { if (stackTop == -1) throwstackEmpty(); stack[stackTop--].~T(); // destructor for T }
Linked Stack template<class T> class linkedStack : public stack<T> { public: linkedStack(intinitialCapacity = 10) {stackTop = NULL; stackSize = 0;} ~linkedStack(); bool empty() const {return stackSize == 0;} int size() const {return stackSize;} T& top() { if (stackSize == 0) throw stackEmpty(); return stackTop->element; } void pop(); void push(const T& theElement); private: chainNode<T>* stackTop; // pointer to stack top intstackSize; // number of elements in stack };
Push() template<class T> void linkedStack<T>::push(const T& theElement) { stackTop = new chainNode<T>(theElement, stackTop); stackSize++; }
Pop() template<class T> void linkedStack<T>::pop() {// Delete top element. if (stackSize == 0) throw stackEmpty(); chainNode<T>* nextNode = stackTop->next; delete stackTop; stackTop = nextNode; stackSize--; }
Implement stack • derivedArrayStack.h • derivedLinkedStack.h • arrayStack.h • linkedStack.h
Parentheses Matching • (((a+b)*c+d-e)/(f+g)-(h+j)*(k-l))/(m-n) • Output pairs (u,v) such that the left parenthesis atposition u is matched with the right parenthesis at v. • (2,6)(1,13) (15,19)(21,25) (27,31)(0,32)(34,38) • (a+b))*((c+d) • (0,4) • right parenthesis at 5 has no matching left parenthesis • (8,12) • left parenthesis at 7 has no matching right parenthesis
Parentheses Matching • scan expression from left to right • when a left parenthesis is encountered, add its position to the stack • when a right parenthesis is encountered, remove matching position from stack
Example • (((a+b)*c+d-e)/(f+g)-(h+j)*(k-l))/(m-n) 2 1 0
Example • (((a+b)*c+d-e)/(f+g)-(h+j)*(k-l))/(m-n) 1 0 (2,6)
Example • (((a+b)*c+d-e)/(f+g)-(h+j)*(k-l))/(m-n) 15 1 0 (2,6) (1,13)
Example • (((a+b)*c+d-e)/(f+g)-(h+j)*(k-l))/(m-n) 21 1 0 (2,6) (1,13) (15,19)
Example • (((a+b)*c+d-e)/(f+g)-(h+j)*(k-l))/(m-n) 27 1 0 (2,6) (1,13) (15,19) (21,25)
Example • (((a+b)*c+d-e)/(f+g)-(h+j)*(k-l))/(m-n) 1 0 (2,6) (1,13) (15,19) (21,25) (27,31) (0,32) • and so on
Homework 2.1 • Write a program that look for matched pairs of parentheses and matched pairs of brackets ([]) and report a nesting problem. • For example: in the string (a+[b*(c-d)+f]), the output should be (0,14),(3,13),(6,10).
4 3 2 1 A B C Towers Of Hanoi/Brahma • 64 gold disks to be moved from tower A to tower C • each tower operates as a stack • cannot place big disk on top of a smaller one
3 2 1 B C Towers Of Hanoi/Brahma • 3-disk Towers Of Hanoi/Brahma A
2 1 3 B C Towers Of Hanoi/Brahma • 3-disk Towers Of Hanoi/Brahma A
1 2 3 B C Towers Of Hanoi/Brahma • 3-disk Towers Of Hanoi/Brahma A
3 1 2 B C Towers Of Hanoi/Brahma • 3-disk Towers Of Hanoi/Brahma A
3 2 1 B C Towers Of Hanoi/Brahma • 3-disk Towers Of Hanoi/Brahma A
3 2 1 B C Towers Of Hanoi/Brahma • 3-disk Towers Of Hanoi/Brahma A