Stack
Stack
Stack
Stack Overview
• Stack ADT
• Basic operations of stack
– Pushing, popping etc.
• Implementations of stacks using
– array
– linked list
What is a Stack?
• A stack is a list ADT with the restriction that insertions
and deletions can be performed in only one position,
namely, the end of the list, called the top.
pop push(o)
Top 3
2
7
6
The Stack ADT
• Fundamental operations:
– Push: Equivalent to an insert
– Pop: Deletes the most recently inserted
element
– Top: Examines the most recently inserted
element
Stack ADT
• Stacks are less flexible
but are more efficient and easy to implement
top
B
top top A
A A
top
Implementation of Stacks
• Any list implementation could be used to implement a
stack
• Push
– (1) Increment TopOfStack by 1.
– (2) Set Stack[TopOfStack] = X
• Pop
– (1) Set return value to Stack[TopOfStack]
– (2) Decrement TopOfStack by 1
arr
0 1 3 4 6 7 8 9
2 5
A A B C D
top
Implementation by Array
• use Array with a top index pointer as an implementation
of stack
Push(E)
arr
0 1 3 4 6 7 8 9
2 5
A A B C D E
top
Implementation by Array
• use Array with a top index pointer as an implementation
of stack
Push(F)
arr
0 1 3 4 6 7 8 9
2 5
A A B C D E F
top
Implementation by Array
• use Array with a top index pointer as an implementation
of stack
Pop()
arr
0 1 3 4 6 7 8 9
2 5
A A B C D E F
top
Stack class
class Stack {
public:
Stack(int size);; // constructor
~Stack() { delete [] values; } // destructor
bool IsEmpty() { return top == -1; }
bool IsFull() { return top == maxTop; }
double Top();
void Push(double x);
double Pop();
void DisplayStack();
private:
int maxTop; // max stack size = size - 1
int top; // current top of stack
double* values; // element array
};
Stack class
• Attributes of Stack
– maxTop: the max size of stack
– top: the index of the top element of stack
– values: point to an array which stores elements of stack
• Operations of Stack
– IsEmpty: return true if stack is empty, return false
otherwise
– IsFull: return true if stack is full, return false otherwise
– Top: return the element at the top of stack
– Push: add an element to the top of stack
– Pop: delete the element at the top of stack
– DisplayStack: print all the data in the stack
Create Stack
• The constructor of Stack
– Allocate a stack array of size.
– When the stack is full, top will have its maximum
value, i.e. size – 1.
– Initially top is set to -1. It means the stack is empty.
Stack::Stack(int size) {
maxTop = size - 1;
values = new double[size];
top = -1;
}
double Stack::Top() {
if (IsEmpty()) {
cout << "Error: the stack is empty." << endl;
return -1;
}
else
return values[top];
}
Printing all the elements
• void DisplayStack()
– Print all the elements
void Stack::DisplayStack() {
cout << "top -->";
for (int i = top; i >= 0; i--)
cout << "\t|\t" << values[i] << "\t|" << endl;
cout << "\t|---------------|" << endl;
}
Using Stack
result
int main(void) {
Stack stack(5);
stack.Push(5.0);
stack.Push(6.5);
stack.Push(-3.0);
stack.Push(-8.0);
stack.DisplayStack();
cout << "Top: " << stack.Top() << endl;
stack.Pop();
cout << "Top: " << stack.Top() << endl;
while (!stack.IsEmpty()) stack.Pop();
stack.DisplayStack();
return 0;
}
Implementation based on Linked List
• Now let us implement a stack based on a
linked list
head
a1 a2 a3 a4
Stack class
struct Node {
double data; //data
Node* next; //pointer to next node
};
class Stack {
public:
Stack() {top=NULL; size=0;}; // constructor
~Stack(); // destructor
bool IsEmpty() { return top==NULL; }
double Top();
void Push(double x);
double Pop();
void DisplayStack();
private:
Node* top;
int size;
};
Push Stack
void Stack::Push(double x) {
node *newTop = new node;
newTop->data = x;
if(top == NULL){
newTop->next = NULL;
}
else {
newTop->next = top;
}
top = newTop; size++;
}
Pop Stack
double Stack::Pop() {
if(IsEmpty()) {
cout<<“Error: Stack is empty”<<endl;
return(-1);
}
else {
double val=top->data;
node* old=top;
top=top->next;
size--;
delete old;
return(val);
}
}
Stack Top
double Stack::Top() {
if(IsEmpty()) {
cout<<“Error: Stack is empty”<<endl;
return(-1);
}
else
return top->data;
}
Destructor
Stack::~Stack(void) {
Node* currNode = top;
Node* nextNode = NULL;
while (currNode != NULL)
{
nextNode = currNode->next;
// destroy the current node
delete currNode;
currNode = nextNode;
}
}
Printing all the elements
• void DisplayStack()
– Print all the elements
void Stack::DisplayStack() {
cout << "top -->";
Node* currNode = top;
while (currNode != NULL){
cout << “\t|\t” << currNode->data << “\t|”<<endl;
currNode = currNode->next;
}
cout << "\t|---------------|" << endl;
}
Using Stack (linked list)
result
int main(void) {
Stack *s = new Stack;
s->Push(5.0);
s->Push(6.5);
s->Push(-3.0);
s->Push(-8.0);
s->DisplayStack();
cout << "Top: " << s->Top() << endl;
s->Pop();
cout << "Top: " << s->Top() << endl;
while (!s->IsEmpty()) s->Pop();
s->DisplayStack();
return 0;
}
Applications
• Many application areas use stacks:
– line editing
– bracket matching
– postfix calculation
– function call stack
Line Editing
• A line editor would place characters read into a
buffer but may use a backspace symbol (denoted by
) to do error correction
• Refined Task
– read in a line
– correct the errors via backspace
– print the corrected line in reverse
Input : abc_defgh2klpqrwxyz
Stack
Reversed Output : zyf
Bracket Matching Problem
• Ensures that pairs of brackets are properly matched
• An Example: {a,(b+f[4])*3,d+f[5]}
• Bad Examples:
Stack
Prefix, Postfix, Infix Notation
Infix Notation
• To add A, B, we write
A+B
• To multiply A, B, we write
A*B
• The operators ('+' and '*') go in between the
operands ('A' and 'B')
• This is "Infix" notation.
Prefix/Polish Notation
• Instead of saying "A plus B", we could say "add
A,B " and write
+AB
• "Multiply A,B" would be written
*AB
• This is Prefix notation.
Postfix/Reverse Polish Notation
• Another alternative is to put the operators
after the operands as in
AB+
and
AB*
• This is Postfix notation.
• The terms infix, prefix, and postfix tell us
whether the operators go between, before, or
after the operands.
Parentheses
• Evaluate 2+3*5.
• + First:
(2+3)*5 = 5*5 = 25
• * First:
2+(3*5) = 2+15 = 17
• Infix notation requires Parentheses.
What about Prefix Notation?
• +2*35=
=+2*35
= + 2 15 = 17
• *+235=
=*+235
= * 5 5 = 25
• No parentheses needed!
Postfix Notation
• 235*+=
=235*+
= 2 15 + = 17
• 23+5*=
=23+5*
= 5 5 * = 25
• No parentheses needed here either!
Conclusion:
• Infix is the only notation that requires
parentheses in order to change the order in
which the operations are done.
Fully Parenthesized Expression
• A FPE has exactly one set of Parentheses
enclosing each operator and its operands.
• Which is fully parenthesized?
(A+B)*C
( ( A + B) * C )
( ( A + B) * ( C ) )
Infix to Prefix Conversion
Move each operator to the left of its operands &
remove the parentheses:
( ( A + B) * ( C + D ) )
Infix to Prefix Conversion
Move each operator to the left of its operands &
remove the parentheses:
(+A B *(C+D))
Infix to Prefix Conversion
Move each operator to the left of its operands &
remove the parentheses:
*+A B (C+D)
Infix to Prefix Conversion
Move each operator to the left of its operands &
remove the parentheses:
*+A B +C D
A B+C* D E+F/-
• Operand order does not change!
• Operators are in order of evaluation!
Computer Algorithm
FPE Infix To Postfix
• Assumptions:
1. Space delimited list of tokens represents a
FPE infix expression
2. Operands are single characters.
3. Operators +,-,*,/
FPE Infix To Postfix
• Initialize a Stack for operators, output list
• Split the input into a list of tokens.
• for each token (left to right):
if it is operand: append to output
if it is operator or '(': push onto Stack
if it is ')': pop operators & append till '('
FPE Infix to Postfix
(((A+B)*(C-E))/(F+G))
• stack: <empty>
• output: []
FPE Infix to Postfix
((A+B)*(C-E))/(F+G))
• stack: (
• output: []
FPE Infix to Postfix
(A+B)*(C-E))/(F+G))
• stack: ( (
• output: []
FPE Infix to Postfix
A+B)*(C-E))/(F+G))
• stack: ( ( (
• output: []
FPE Infix to Postfix
+B)*(C-E))/(F+G))
• stack: ( ( (
• output: [A]
FPE Infix to Postfix
B)*(C-E))/(F+G))
• stack: ( ( ( +
• output: [A]
FPE Infix to Postfix
)*(C-E))/(F+G))
• stack: ( ( ( +
• output: [A B]
FPE Infix to Postfix
*(C-E))/(F+G))
• stack: ( (
• output: [A B + ]
FPE Infix to Postfix
(C-E))/(F+G))
• stack: ( ( *
• output: [A B + ]
FPE Infix to Postfix
C-E))/(F+G))
• stack: ( ( * (
• output: [A B + ]
FPE Infix to Postfix
-E))/(F+G))
• stack: ( ( * (
• output: [A B + C ]
FPE Infix to Postfix
E))/(F+G))
• stack: ( ( * ( -
• output: [A B + C ]
FPE Infix to Postfix
))/(F+G))
• stack: ( ( * ( -
• output: [A B + C E ]
FPE Infix to Postfix
)/(F+G))
• stack: ( ( *
• output: [A B + C E - ]
FPE Infix to Postfix
/(F+G))
• stack: (
• output: [A B + C E - * ]
FPE Infix to Postfix
(F+G))
• stack: ( /
• output: [A B + C E - * ]
FPE Infix to Postfix
F+G))
• stack: ( / (
• output: [A B + C E - * ]
FPE Infix to Postfix
+G))
• stack: ( / (
• output: [A B + C E - * F ]
FPE Infix to Postfix
G))
• stack: ( / ( +
• output: [A B + C E - * F ]
FPE Infix to Postfix
))
• stack: ( / ( +
• output: [A B + C E - * F G ]
FPE Infix to Postfix
)
• stack: ( /
• output: [A B + C E - * F G + ]
FPE Infix to Postfix
• stack: <empty>
• output: [A B + C E - * F G + / ]
Problem with FPE
• Too many parentheses.
• Establish precedence rules:
• We can alter the previous program to use the
precedence rules.
Infix to Postfix
• Initialize a Stack for operators, output list
• Split the input into a list of tokens.
• for each token (left to right):
if it is operand: append to output
if it is '(': push onto Stack
if it is ')': pop & append till '('
if it in '+-*/':
while top has precedence ≥ it:
pop & append the operator
push onto Stack
At end pop and append the rest of the operators in Stack.
Infix to Postfix
A * (B + C * D) + E
• stack: <empty>
• output: []
Infix to Postfix
* (B + C * D) + E
• stack: <empty>
• output: [A]
Infix to Postfix
(B + C * D) + E
• stack: <*>
• output: [A]
Infix to Postfix
B + C * D) + E
• stack: <*(>
• output: [A]
Infix to Postfix
+ C * D) + E
• stack: <*(>
• output: [AB]
Infix to Postfix
C * D) + E
• stack: <*(+>
• output: [AB]
Infix to Postfix
* D) + E
• stack: <*(+>
• output: [ABC]
Infix to Postfix
D) + E
• stack: <*(+*>
• output: [ABC]
Infix to Postfix
)+E
• stack: <*(+*>
• output: [ABCD]
Infix to Postfix
+E
• stack: <*(+*)>
• output: [ABCD]
Infix to Postfix
+E
• stack: <*>
• output: [ABCD*+]
Infix to Postfix
E
• stack: <+>
• output: [ABCD*+*]
Infix to Postfix
• stack: <+>
• output: [ABCD*+*E]
Infix to Postfix
• stack: <empty>
• output: [ABCD*+*E+]
Homework
• Convert infix to postfix using stack:
(A + B + C) ^ D * ( E + F )/G
Precedence: ^
*,/
+,-
Evaluating Postfix Expression
Initialise stack S
For each item read.
If it is an operand,
push on the stack 234+*
If it is an operator,
pop arguments from stack;
perform operation;
push result onto the stack
Expr
2 push(2)
3 push(3)
4 push(4)
+ arg2=Pop()
Arg1=Pop()
4
push(arg1+arg2) 3+4=7
3
* arg2=Pop() 2*7=14
2
arg1=Pop()
Stack
push(arg1*arg2)
Homework
• Evaluate the postfix expression using stack
4 5 + 2 + 2 ^ 3 4 + * 7 /