Download presentation
Presentation is loading. Please wait.
1
5.4 Additional Stack Applications
5.3 Implementing a Stack 5.4 Additional Stack Applications Chapter 5 – The Stack
2
Attendance Quiz #19 Stacks
3
Tip #20: Initialization Lists
Stacks One aspect of C++ that isn't fickle is the order in which an object's data is initialized. The order is always the same: Base classes are initialized before derived classes. Within a class, data members are initialized in the order in which the are declared. To avoid reader confusion, as well as the possibility of some truly obscure behavioral bugs, always list members in the initialization list in the same order as they're declared in the class. class MyClass { private: string name; string address; public: MyClass(const string& n, const string& a) : address(a), name(n) { } }; class MyClass { private: string name; string address; public: MyClass(const string& n, const string& a) : name(n), address(a) { } };
4
Abstract Data Type Stacks An Abstract Data Type (ADT) is a mathematical model for a data type as seen from a users point of view. In contrast to data structures, which are concrete representations of data, as seen from the implementers point of view, no the users. ADT's support abstraction, encapsulation, and information hiding. A user implementation of an ADT has: private data hidden inside the class, a collection of public operations to manipulate the data, and additional private operations hidden inside the class. For example, a cell phone has buttons for various operations, but it is not necessary to understand how the phone works in order to use it!
5
Abstract Data Type Examples of common built-in ADTs:
Stacks Examples of common built-in ADTs: boolean Values: true and false Operations: and, or, not, nand, etc. integer Values: Whole numbers between MIN and MAX values Operations: add, subtract, multiply, divide, etc. Examples of common user-defined ADTs: vector Values: Vector elements (ie., vector of X's,…) Operations: initialize, push_back, pop_back, at, erase, swap, size, etc. list Operations: initialize, front, back, size, merge, sort, etc. stack Values: Stack elements (ie., stack of X's,…) Operations: push, pop, top, empty size.
6
5.3, pgs. 325-331 5.3 Implementing a Stack
Adapter Classes and the Delegation Pattern Revisiting the Definition File stack.h Implementing a Stack as a Linked Data Structure Comparison of Stack Implementations 5.3, pgs
7
The Stack ADT A stack is similar to a vector.
Stacks A stack is similar to a vector. The standard library defines the stack as a template class that takes any of the sequential containers (vector, list, or deque. Implementations use sequential containers: A contiguous container (such as a vector), A linked container (such as special-purpose single-linked list.)
8
deque<Item_Type> for vector<Item_Type>
myStack.h Stacks deque<Item_Type> for vector<Item_Type> #ifndef MY_STACK_H_ #define MY_STACK_H_ #include <vector> template <typename T> class Stack { private: std::vector<T> myStack; public: /** Construct an empty stack */ Stack() {} /** Push item on stack */ void push(const T& item) { myStack.push_back(item); } /** Return top of stack */ T& top() { return myStack.back(); } /** Pop top of stack */ void pop() { myStack.pop_back(); } /** Return TRUE if stack is empty */ bool empty() const { return myStack.size() == 0; } /** Return number of stack entries */ size_t size() const { myStack.size(); } }; #endif // MY_STACK_H_ All sequential containers provide the functions empty, size, back (equivalent to stack::top), push_back (equivalent to stack::push) and pop_back (equivalent to stack::pop), so we could use any of these containers. The stack class uses the delegation pattern by making the functions in the underlying container class do its work. A stack is an adapter class because it adapts the functions available in another class to the interface its clients expect by giving different names to essentially the same operations.
9
Linked List Stack Stacks We can also implement a stack using a linked list of nodes push() inserts a node at the head of the list. top_of_stack = new Node(item, top_of_stack); top_of_stack->next references the old top of stack top() returns top_of_stack->data. pop() resets top_of_stack to the value stored in the next field of the list head and then deletes the old top of the stack (pointed to by old_top). When the stack is empty, top_of_stack == NULL.
10
Comparing Stack Implementations
Stacks The linked list implementation is similar to the implementation provided by the C++ standard library. By delegating the operations to an underlying sequential container, we avoid having to implement these operations ourselves. By using the functions push_back, pop_back, and back, we are assured of constant time (O(1)) performance, since the C++ standard requires that implementations of the sequential containers provide these operations in (amortized) constant time. Making a copy of the stacked item (or reference) is not considered – probably a wash. All stack operations using a sequential container (such as a vector, linked list, or deque) are O(1).
11
Comparing Stack Implementations
Stacks Use of the standard containers has a space penalty. To achieve the amortized constant performance for push_back, and so forth, the vector and deque allocate additional space. The vector will allocate an array twice the current size whenever it needs to allocate additional space. (The deque also allocates additional space.) While using a linked data structure has the advantage of using exactly as much storage as is needed for the stack, you do need to allocate storage for the links. The standard list class is a double-linked list; thus each Node contains pointers to both a next and a previous entry (not needed for the stack.) Because all insertions and deletions are at one end, the flexibility provided by a linked data structure is under-utilized.
12
5.4, pgs. 332-347 5.4 Additional Stack Applications
Case Study: Evaluating Postfix Expressions Case Study: Converting from Infix to Postfix Case Study: Part 2: Converting Expressions with Parentheses 5.4, pgs
13
Postfix and infix notation
Stacks Postfix and infix notation Expressions normally are written in infix form, but it easier for a computer to evaluate an expression in postfix form since there is no need to group sub-expressions in parentheses or worry about operator precedence Save operands on a stack until their associated operator is scanned, then pop the operands, compute the result, and push it back onto the stack. Assume binary operators and disallow negative operands.
14
Evaluating Postfix Expressions
Stacks 4 4 7 * 20 - 1. Empty the operand stack 2. while there are more tokens 3. get the next token 4. if the first character of the token is a digit push the token on the stack 6. else if the token is an operator pop the right operand off the stack pop the left operand off the stack evaluate the operation push the result onto the stack 11. pop the stack and return the result 4
15
Evaluating Postfix Expressions
Stacks 4 4 7 7 * 20 - 1. Empty the operand stack 2. while there are more tokens 3. get the next token 4. if the first character of the token is a digit push the token on the stack 6. else if the token is an operator pop the right operand off the stack pop the left operand off the stack evaluate the operation push the result onto the stack 11. pop the stack and return the result 7 4
16
Evaluating Postfix Expressions
Stacks * 4 4 7 7 * 20 - 1. Empty the operand stack 2. while there are more tokens 3. get the next token 4. if the first character of the token is a digit push the token on the stack 6. else if the token is an operator pop the right operand off the stack pop the left operand off the stack evaluate the operation push the result onto the stack 11. pop the stack and return the result 7 4
17
Evaluating Postfix Expressions
Stacks 28 4 4 7 7 * 20 - 1. Empty the operand stack 2. while there are more tokens 3. get the next token 4. if the first character of the token is a digit push the token on the stack 6. else if the token is an operator pop the right operand off the stack pop the left operand off the stack evaluate the operation push the result onto the stack 11. pop the stack and return the result
18
Evaluating Postfix Expressions
Stacks 4 4 7 7 * 20 20 - 1. Empty the operand stack 2. while there are more tokens 3. get the next token 4. if the first character of the token is a digit push the token on the stack 6. else if the token is an operator pop the right operand off the stack pop the left operand off the stack evaluate the operation push the result onto the stack 11. pop the stack and return the result 28
19
Evaluating Postfix Expressions
Stacks 4 4 7 7 * 20 20 - 1. Empty the operand stack 2. while there are more tokens 3. get the next token 4. if the first character of the token is a digit push the token on the stack 6. else if the token is an operator pop the right operand off the stack pop the left operand off the stack evaluate the operation push the result onto the stack 11. pop the stack and return the result 28
20
Evaluating Postfix Expressions
Stacks - 4 4 7 7 * 20 - 20 28 1. Empty the operand stack 2. while there are more tokens 3. get the next token 4. if the first character of the token is a digit push the token on the stack 6. else if the token is an operator pop the right operand off the stack pop the left operand off the stack evaluate the operation push the result onto the stack 11. pop the stack and return the result 20 28
21
Evaluating Postfix Expressions
Stacks 8 4 4 7 7 * 20 - 1. Empty the operand stack 2. while there are more tokens 3. get the next token 4. if the first character of the token is a digit push the token on the stack 6. else if the token is an operator pop the right operand off the stack pop the left operand off the stack evaluate the operation push the result onto the stack 11. pop the stack and return the result 8
22
Evaluating Postfix Expressions
Stacks 4 4 7 7 * 20 - 1. Empty the operand stack 2. while there are more tokens 3. get the next token 4. if the first character of the token is a digit push the token on the stack 6. else if the token is an operator pop the right operand off the stack pop the left operand off the stack evaluate the operation push the result onto the stack 11. pop the stack and return the result 8
23
Evaluating Postfix Expressions
Stacks Testing: write a driver which creates a Postfix_Evaluator object reads one or more expressions and reports the result catches the Syntax_Error exception. exercises each path by using each operator exercises each path through eval by trying different orderings and multiple occurrences of operators tests for syntax errors: an operator without any operands a single operand an extra operand an extra operator a variable name the empty string
24
Using the expression: [(43 + {2}) * (19)]
Determinine if it is balanced. Convert to Postfix. Evaluate the expression.
25
Convert Infix to Postfix
26
Converting from Infix to Postfix
Stacks Assume: expressions consists of only spaces, operands, and operators space is a delimiter character all operands that are identifiers begin with a letter all operands that are numbers begin with a digit For expressions without parentheses, there are two criteria that determine the order of operator evaluation: Operators are evaluated according to their precedence or rank; higher- precedence operators are evaluated before lower-precedence operators. For example, *, /, and % (the multiplicative operators) are evaluated before +, – Operators with the same precedence are evaluated in left-to-right order (left associative rule) Example convert: w – 5.1 / sum * 2 to its postfix form: w 5.1 sum / 2 * -
27
Converting from Infix to Postfix
Stacks By temporarily storing the operators on a stack, we can pop them when needed and insert them in the postfix string in an order that indicates when they should be evaluated For example, if we have the first two operators from the string "w / sum * 2" stored on a stack as follows: The operator “/” (scanned second) must come off the stack and be placed in the postfix string before the operator - (scanned first) If we have the stack as just shown and the next operator is “*”, we need to pop the “/” off the stack and insert it in the postfix string before “*”, because the multiplicative operator scanned earlier (/) should be evaluated before the multiplicative operator (*) scanned later (the left- associative rule) / -
28
Converting from Infix to Postfix
Stacks
29
Converting from Infix to Postfix
Stacks
30
Infix to Postfix Example
Stacks Infix Expression: (w * [x + y] / z) Postfix Expression: 1 4 5 6 7 8 9 10 3 2 ( w x + y ] / z ) [ * ( ( balanced : true index : 0
31
Infix to Postfix Example
Stacks Infix Expression: (w * [x + y] / z) Postfix Expression: ( w 1 4 5 6 7 8 9 10 3 2 ( w x + y ] / z ) [ * ( balanced : true index : 1
32
Infix to Postfix Example
Stacks Infix Expression: (w * [x + y] / z) Postfix Expression: w 1 4 5 6 7 8 9 10 3 2 ( w x + y ] / z ) [ * ( * ( balanced : true index : 2
33
Infix to Postfix Example
Stacks Infix Expression: (w * [x + y] / z) Postfix Expression: w 1 4 5 6 7 8 9 10 3 2 ( w x + y ] / z ) [ * ( [ * ( balanced : true index : 3
34
Infix to Postfix Example
Stacks Infix Expression: (w * [x + y] / z) Postfix Expression: w x 1 4 5 6 7 8 9 10 3 2 ( w x + y ] / z ) [ * ( [ * ( balanced : true index : 4
35
Infix to Postfix Example
Stacks Infix Expression: (w * [x + y] / z) Postfix Expression: w x 1 4 5 6 7 8 9 10 3 2 ( w x + y ] / z ) [ * ( + [ * ( balanced : true index : 5
36
Infix to Postfix Example
Stacks Infix Expression: (w * [x + y] / z) Postfix Expression: w x y 1 4 5 6 7 8 9 10 3 2 ( w x + y ] / z ) [ * ( + [ * ( balanced : true index : 6
37
Infix to Postfix Example
Stacks Infix Expression: (w * [x + y] / z) Postfix Expression: + w x y 1 4 5 6 7 8 9 10 3 2 ( w x + y ] / z ) [ * ( ] + [ [ * ( balanced : true index : 7
38
Infix to Postfix Example
Stacks Infix Expression: (w * [x + y] / z) Postfix Expression: * w x y + 1 4 5 6 7 8 9 10 3 2 ( w x + y ] / z ) [ * ( / * ( balanced : true index : 8
39
Infix to Postfix Example
Stacks Infix Expression: (w * [x + y] / z) Postfix Expression: w x y + * z 1 4 5 6 7 8 9 10 3 2 ( w x + y ] / z ) [ * ( / ( balanced : true index : 9
40
Infix to Postfix Example
Stacks Infix Expression: (w * [x + y] / z) Postfix Expression: * / w x y + * z 1 4 5 6 7 8 9 10 3 2 ( w x + y ] / z ) [ * ( ) ( / ( balanced : true index : 10
41
For each of the following expressions
1) Check for balance 2) Convert to Postfix 3) Evaluate expression [ ] ( 5 ) 40 * { ( ) } - 4 / 5 / 6 [ ] / 4 [ ( ) * { } - ( 2 / 2 ) ] + 24 / 3
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.