34
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 Structures600 Stack Stack is one the most useful ADTs. Like list, it is a collection of data items. Supports “LIFO” (Last In First Out) discipline

Embed Size (px)

Citation preview

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 (.