COP3530 Data Structures600 Stack Stack is one the most useful ADTs. Like list, it is a collection of...
-
Upload
juliet-carr -
Category
Documents
-
view
213 -
download
0
Transcript of COP3530 Data Structures600 Stack Stack is one the most useful ADTs. Like list, it is a collection of...
COP3530 Data Structures 1
Stack• Stack is one the most useful ADTs.• Like list, it is a collection of data items.• Supports “LIFO” (Last In First Out) discipline.
– The last data added is the one retrieved next.• Access to data members is governed by the FIFO
discipline. You can’t access any item you want!!• There are lots of applications that depend of the
use of stack ADT.• Stack are also very useful for search applications
such as Exhaustive Search or Tree Search.• Stacks are used to implement Recursion in C++.
COP3530 Data Structures 2
Developing Stack ADT• Application: Read and Store a line of text.• Problem: User can use backspace which should
delete the previous character.• Data: Characters typed from keyboard until \n.• Need: An ADT to store the characters and manage// read a line, correcting mistakes along the way.while (not at end of line) read a new character ch. if ch is not backspace add ch to the ADT else remove the most recent item from ADT.
COP3530 Data Structures 3
Developing Stack ADT (contd)• Two ADT operations required
– Add a new item to the ADT– Remove the item added most recently
• What do we do if there is no data and the user enters backspace?– We can either check ADT for emtpy before remove– Remove can do nothing if it is empty or fail.
• What operations do we need to write the text?– If we write it backward, we need a way to retrieve
the item added most recently.– If we write it forward, we have a problem. We need
a temporary stack to reverse the items to print.
COP3530 Data Structures 4
Reading a Line of TextStack stack; char ch;while (cin >> ch && ch != ‘\n’){ if (ch != ‘\b’) { Add item to stack. } else if (stack is not empty) { Remove item from stack; } else { ; // Ignore ch. Do nothing. }}
COP3530 Data Structures 5
Printing Line of Text// Write the text in reverse order.while (stack is not empty){ retrive an item from stack into ch. cout << ch; remove the item from stack.}
// Write the text in forward order.Stack tempStack;
// move items from stack to tempStack.// tempStack has items in reverse order.// Print items from tempStack as above.
COP3530 Data Structures 6
ADT Stack Operations• Create an empty stack• Destroy a stack• Determine whether the stack is empty• Add an item to the stack• Retrieve an item from the stack (not removed).• Remove an item from the stackAlternative design for the last operation:• Retrieve and Remove an item from stackInstead of replacing the last operation with this, we
can give this as an additional operation.
COP3530 Data Structures 7
Stack ADT specification// Constructor to create an empty stack.Stack();
// Destructor to destroy the stack.~Stack();
// Test whether the stack is emtpybool Emtpy() const;
// Add an item to the stackvoid Push(const StackItem& item, bool& success);
COP3530 Data Structures 8
Stack ADT specification (contd)// Remove an item from stack.void Pop(bool& success);
// Retrieve and Remove and item.void Pop(StackItem& item, bool& success);
// Retrieve an item from stack.void Top(StackItem& item, bool& success);
If the stack is array based and does not expand then we can also provide,
// Check whether the stack is fullvoid Full() const;
COP3530 Data Structures 9
ExampleStack Stack; emptybool success;StackItem item; Top stack.Push(5, success); 5stack.Push(8, success); 8 5stack.Push(1, success); 1 8 5stack.Pop(success); 8 5stack.Top(item, success); 8 5stack.Pop(success); 5stack.Pop(success); emptystack.Empty() will return true now.
COP3530 Data Structures 10
Copy Constructor• Under what circumstances do we need a copy
constructor for Stack ADT?– we have a function that returns a stack.– we pass the stack by value.– we want to create a stack based on another.
• Normally, we do not need a copy constructor as we do not have the above cases.
• However, it is a good idea to provide constructor instead of depending on the default one provided by the compiler. The code can do nothing.
• Thus, our version will not use a copy constructor.
COP3530 Data Structures 11
Balancing BracesStack stack; bool bal = TRUE; bool succ;while (bal && cin >> ch && ch != ‘\n’){ if (ch == ‘{‘) { stack.Push(ch, succ); } else if (ch == ‘}’) { if (stack.Empty()) { bal = FALSE; } else { stack.Pop(succ); } }} // outside loop, check variable bal.
COP3530 Data Structures 12
Success argument• It is generally not a good idea to ignore success
argument. What if it returns false? • The code can be rewritten in a different way using
the fact that Pop returns false if stack is empty.else if (ch == ‘}’){ stack.Pop(succ); // Try to pop {. if (! succ) { bal = FALSE; // couldn’t pop. No {. }}
COP3530 Data Structures 13
STL Stack Class Usage• Standard Template Library (STL) supports various
classes that are commonly used. In particular, it supports string, vector, stack, queue, list etc.
Operations Supported:empty() Checks if the stack is emptysize() Returns # of elements in stackpop() Pops an item. Stack must be non-empty. Does not return item.top() Returns top item but do not pop. Stack must be non-empty.push(item) Pushes the item into stack.#include <stack>stack<int> myStack;
COP3530 Data Structures 14
Implementation of Stack• There are several design choices available to
implement a stack– Array based– vector based– Linked-list based– List based
• Direct implementation has less overhead.• Using another class such as list or vector has extra
overhead, but it is not significant. Code Reuse is better as the other class is already debugged.
• See page 261 for stack view in all these cases except vector.
COP3530 Data Structures 15
vector-based Stack ADTtypedef int StackItem;class Stack{public: Stack(unsigned int capacity = 100); Stack(const Stack& stack); // copy ~Stack(); // Destructor bool Empty() const; void Pop(bool& success); void Pop(StackItem& item, bool& success); void Push(const StackItem& item, bool& success);
COP3530 Data Structures 16
vector-based Stack ADT (contd) void Top(StackItem& item, bool& success) const; bool Full() const;
private: unsigned int capacity; int top; // index of top item. // -1 if stack is emtpy. vector<StackItem> items;}
COP3530 Data Structures 17
Stack ADT ImplementationStack::Stack(unsigned int capacity=100): this.capacity(capacity), top(-1), items(capacity) {}
bool Stack::Empty() const{ return(top == -1);}
COP3530 Data Structures 18
Implemenation of Stack ADTbool Stack::Full(){ return(top == capacity);}
void Stack::Push(const StackItem& item, bool& success){ if (Full()) { success = FALSE; }
COP3530 Data Structures 19
Implemenation of Stack ADT else { items[++top] = item; success = TRUE; }}void Stack::Pop(StackItem& item, bool& success){ if (Empty()) { success = FALSE; }
COP3530 Data Structures 20
Implemenation of Stack ADT else { item = items[top--]; success = TRUE; }}
The other version of Pop is similar. Just decrement top. item is not supplied.
The version of Top is also same as Pop except that top is not decremented.
COP3530 Data Structures 21
Linked-list based Stack ADT• This is very similar to linked list implementation
but is much simpler.• Top of the stack is the first node.• Insertion of a new item is at front of the linked list
and is hence much easier. No insertion of item in the middle of the list is needed.
• Pop involves deleting the first node. Deletion of any other middle item of the list is not needed.
• Top involves simply accessing the item at first node of the list.
• Empty simply checks if head is NULL.• Exercise: Do the complete implementation.
COP3530 Data Structures 22
Postfix Expressions• Stacks can be used to evaluate postfix expressions.• In postfix expressions, the operator comes after
the operands.• The expression can have both unary and binary
operators. But, we should be able say by simply looking at an operator whether it is unary or binary. So, don’t overload + - etc for both unary and binary operator. Use different symbols in the postfix expression. It is ok in the infix expression.
• 2 + 3 * (5 - 8) infix• 2 3 5 8 - * + postfix.
COP3530 Data Structures 23
Evaluation of Postfix Expression• Scan the expression one item at a time.• If it is an operand, push onto the stack.• If it is an operator, pop proper number of items
from stack, perform the operation, and push the result back onto the stack.
• If the stack does not have enough operands, the expression is invalid.
• At the end of input, check the stack. If it has just one item, that is the answer. Else, the expression is invalid.
• Postfix expressions do not need ( ). They have only operands and operators.
COP3530 Data Structures 24
Evaluation Example• Consider the expression 2 3 4 + 9 * 1 - +Item Stack empty2 23 3 24 4 3 2+ 7 29 9 7 2* 63 21 1 63 2- 62 2 Note: oprnd1 - oprnd2+ 64 Answer is 64.
COP3530 Data Structures 25
Evaluation Code// Assume that we have only binary ops.for each item in the input{ if (item is an operand) { stack.Push(item, success); } else { stack.Pop(oprnd2, success); if (!success) { it is invalid expression. }
COP3530 Data Structures 26
Evaluation Code (contd) stack.Pop(oprnd2, success); if (! success) { invalid expression } result = oprnd1 op oprnd2; stack.Push(result, success); if (! success) { stack overflow } }}
COP3530 Data Structures 27
Evaluation Code (contd)if (stack.Empty()){Invalid expression
}stack.Pop(result);if (!stack.Empty()){ // there is more stuff on stack. Invalid expression}print result.
COP3530 Data Structures 28
Tokens• How do we read the input and determine whether
we have an operand or operator.• First, we need to define what is an operator and
what are operands.• We want a facility to be able to retrieve items one
by one from our input stream (cin or file or even a string).
• How about a class that can do this for us? Sure.• We call each item a token. We can name the class
Token. We need to design the ADT to help our application.
• Java has such classes.
COP3530 Data Structures 29
Infix to Postfix• Stack is also useful for converting an infix
expression to postfix expression.• Infix: (2 + 3) * (4 - 5)• Postfix: 2 3 + 4 5 - *• Informal Technique:
– Write the operands in the same order as in infix.– Start placing one operator at a time at the correct
place starting with the first operator performed in the infix notation.
– ( ) are not needed in postfix expression.
COP3530 Data Structures 30
Infix to Postfix AlgorithmInitialize postfix expression to be emptyfor each item from the infix expression{ if item is operand then place it in postfix else if it is ( then push it on stack. else if it is ) then pop operators until ( from stack and place in postfix. Discard (. else if it is operator then
COP3530 Data Structures 31
Infix to Postfix Algorithm pop all higher or equal precedence operators from stack and place in postfix. Stop at ( or empty stack. Place this operator on to stack. }}pop the operators left on stack and place them in the postfix expression.
Note: If the next operator is same as the one on stack, they have same precedence
We do different things depending on if it is left or right associative.
COP3530 Data Structures 32
Infix to Postfix ExampleInfix Expression: (2 + 3) * 5
Token Stack Postfix ---------------------------------------( (2 ( 2+ + ( 23 + ( 2 3) 2 3 +* * 2 3 +5 * 2 3 + 5 2 3 + 5 *
COP3530 Data Structures 33
Infix to Postfix ExampleInfix: 2 + 3 + 4 * 5 / (6 + 8)Token Stack Postfix ---------------------------------------2 2+ + 23 + 2 3+ + 2 3 +4 + 2 3 + 4* * + 2 3 + 45 * + 2 3 + 4 5/ / + 2 3 + 4 5 *( ( / + 2 3 + 4 5 *
COP3530 Data Structures 34
Infix to Postfix Example( ( / + 2 3 + 4 5 *6 ( / + 2 3 + 4 5 * 6+ + ( / + 2 3 + 4 5 * 68 + ( / + 2 3 + 4 5 * 6 8) / + 2 3 + 4 5 * 6 8 +
Final Exp: 2 3 + 4 5 * 9 8 + / +
• The algorithm works for all kinds of operators as long as we define precedence values for all these operators.
• ( has the lowest precedence when it is on stack.• Stack has only operators and (.