Post on 14-Dec-2015
stacks 2
Stack characteristicsStack characteristics
• Entries are ordered in terms of access -- both insertion and removal take place at same spot (top of stack)
• Specialized type of container class; defining characteristic is insertion/removal order
• LIFO = last in, first out; entries are removed in reverse order of insertion
stacks 3
Stack operationsStack operations
• Push -- insert item on stack
• Pop -- remove item from stack
• Peek -- examine, but don’t remove item
stacks 4
Stack operationsStack operations
• Important to know if stack is empty -- attempt to remove an item from an empty stack is an underflowunderflow error
• Depending on implementation, may be necessary to check if stack is full -- attempt to add item to a full stack is an overflowoverflow error
stacks 5
Implementation of Stack ADTImplementation of Stack ADT
• Stacks can be array based (static or dynamic) or linked list based
• Invariant for static array implementation:– The number of items stored in the stack is
found in member variable used– Items are stored in member variable data, a
static array with the stack bottom at data[0] and the stack top at data[used - 1]
stacks 6
Stack class -- static array versionStack class -- static array versiontemplate <class Item>
class Stack
{
public:
enum {CAPACITY = 64};
Stack ( ); // default constructor
Item pop ( ); // removes top Item
Item peek ( ) const; // reveals top Item
. . .
stacks 7
Stack ADT continuedStack ADT continued
void push (const Item & entry); // adds Item to stack
size_t size ( ) const {return used;}
bool is_empty ( ) const {return used == 0;}
private:
Item data[CAPACITY]; // the stack itself
size_t used; // # of items stored in stack
};
stacks 8
Stack function implementations: Stack function implementations: constructorconstructor
// Postcondition: empty stack is created
template <class Item>
Stack<Item>::Stack( )
{
used = 0;
}
stacks 9
Pop functionPop function// Precondition: stack is not empty
// Postcondition: top item is removed
template <class Item>
Item Stack<Item>::pop ( )
{
assert (!is_empty( ));
used--;
return data[used];
}
stacks 10
Peek functionPeek function
// Precondition: stack is not empty
// Postcondition: top item is revealed
template <class Item>
Item Stack<Item>::peek ( ) const
{
assert (!is_empty( ));
return data[used - 1];
}
stacks 11
Push functionPush function
// Precondition: stack is not full
// Postcondition: an item is inserted on stack
template <class Item>
void Stack<Item>::push(const Item& entry)
{
assert (size() < CAPACITY);
data[used] = entry;
used++;
}
stacks 12
Stack application examplesStack application examples
• Compilers use stacks for a variety of purposes:– syntax analysis: matching brackets,
parentheses, etc.– activation records: structures associated with
functions, keeping track of local variables, return address, etc.
stacks 13
Example application: balanced Example application: balanced parenthesesparentheses
• Pseudocode algorithm:– scan string left to right– if ‘(‘ is encountered, push on stack– if ‘)’ is encountered, and stack is not empty,
pop one ‘(‘ -- if stack is empty, expression is unbalanced
– if stack is empty when entire string has been scanned and analyzed, expression is balanced
stacks 14
A program to test for balanced A program to test for balanced parenthesesparentheses
int main( ){ String user_input; // uses String data type defined in ch. 4 - based on array
cout << "Type a string with some parentheses and no white space:\n"; cin >> user_input;
if (balanced_parentheses(user_input)) cout << "Those parentheses are balanced.\n"; else cout << "Those parentheses are not balanced.\n";
cout << "That ends this balancing act.\n"; return EXIT_SUCCESS;}
stacks 15
balanced_parentheses functionbalanced_parentheses function
bool balanced_parentheses(const String& expression)// Library facilities used: assert.h, stack1.h, stdlib.h, mystring.h.{ // Meaningful names for constants const char LEFT_PARENTHESIS = '('; const char RIGHT_PARENTHESIS = ')';
Stack<char> store; // Stack to store the left parentheses as they occur size_t i; // An index into the String char next; // The next character from the String char discard; // A char popped off the stack and thrown away bool failed = false; // Becomes true if a needed parenthesis is not found. . .
stacks 16
balanced_parentheses continuedbalanced_parentheses continuedfor (i = 0; !failed && (i < expression.length( )); i++) { next = expression[i]; if (next == LEFT_PARENTHESIS) { if (store.size( ) < store.CAPACITY); store.push(next); } else if ((next == RIGHT_PARENTHESIS) && (!store.is_empty( ))) discard = store.pop( ); else if ((next == RIGHT_PARENTHESIS) && (store.is_empty( ))) failed = true; }
return (store.is_empty( ) && !failed);}
stacks 17
Stack ADT as linked listStack ADT as linked list
• Can make use of toolkit functions to simplify task
• Stack can grow & shrink as needed to accommodate data -- no fixed size
• Invariant:– stack items are stored in a linked list– member variable top is head pointer to list
stacks 18
Class definition for new StackClass definition for new Stack
template <class Item>
class Stack
{
public:
Stack( ) { top = NULL; }
Stack(const Stack& source);
~Stack( ) { list_clear(top); }
...
stacks 19
Stack definition continuedStack definition continued
void push(const Item& entry);
Item pop( );
void operator =(const Stack& source);
size_t size( ) const {return list_length(top);}
bool is_empty( ) const {return top == NULL;}
Item peek( ) const;
private:
Node<Item> *top; // Points to top of stack
};
stacks 20
Push functionPush function
template <class Item>
void Stack<Item>::push(const Item& entry)
{
list_head_insert(top, entry);
}
stacks 21
Pop functionPop function
template <class Item>
Item Stack<Item>::pop( )
{
assert(!is_empty( ));
Item answer = top->data;
list_head_remove(top);
return answer;
}
stacks 22
Peek functionPeek function
template <class Item>
Item Stack<Item>::peek( ) const
{
assert(!is_empty( ));
return top->data;
}
stacks 23
Copy constructorCopy constructor
template <class Item>
Stack<Item>::Stack(const Stack<Item>& source)
{
list_copy(source.top, top);
}
stacks 24
Assignment operatorAssignment operatortemplate <class Item>
void Stack<Item>::operator =(const Stack<Item>& source)
{
if (source.top== top) // Handle self-assignment
return;
list_clear(top);
list_copy(source.top, top);
}
stacks 25
A stack-based calculatorA stack-based calculator
• Input to program is a fully-parenthesized expression -- examples:((5.3 * 1.2) / 3.1)
(4 - 3)
• Two stacks are used -- one for operators, one for operands
• Right parenthesis is signal to pop the stacks and evaluate the expression
stacks 26
Algorithm for expression Algorithm for expression evaluationevaluation
• Evaluate leftmost, innermost expression; continue evaluating, left to right– Read each part of expression– Push numbers on operand stack, operators on
operator stack– When right parenthesis is encountered, pop the
stacks, evaluate, and push result on operand stack
stacks 27
Code for stack calculatorCode for stack calculator
int main( )
{
double answer;
cout << "Type a fully parenthesized arithmetic expression:" << endl;
answer = read_and_evaluate(cin);
cout << "That evaluates to " << answer << endl;
return EXIT_SUCCESS;
}
stacks 28
Code for stack calculatorCode for stack calculatordouble read_and_evaluate(istream& ins)
{
const char DECIMAL = '.';
const char RIGHT_PARENTHESIS = ')';
Stack<double> numbers;
Stack<char> operations;
double number;
char symbol;
...
stacks 29
Code for stack calculatorCode for stack calculator
while (!ins.eof( ) && ins.peek( ) != '\n')
{
if (isdigit(ins.peek( )) || (ins.peek( ) == DECIMAL))
{
ins >> number;
numbers.push(number);
} …
stacks 30
Code for stack calculatorCode for stack calculator
else if (strchr("+-*/", ins.peek( )) != NULL)
{
ins >> symbol;
operations.push(symbol);
}
stacks 31
Code for stack calculatorCode for stack calculator
else if (ins.peek( ) == RIGHT_PARENTHESIS)
{
cin.ignore( );
evaluate_stack_tops(numbers, operations);
}
else
cin.ignore( );
} // end of while loop
return numbers.pop( );
}
stacks 32
Code for stack calculatorCode for stack calculator
void evaluate_stack_tops(Stack<double>& numbers, Stack<char>& operations)
{
double operand1, operand2;
operand2 = numbers.pop( );
operand1 = numbers.pop( );
...
stacks 33
Code for stack calculatorCode for stack calculator
switch (operations.pop( ))
{
case '+':
numbers.push(operand1 + operand2);
break;
case '-':
numbers.push(operand1 - operand2);
break;
...