Stacks Data structures
A stack is a linear data structure, (A Linear data structure have data elements
arranged in sequential manner and each member element is connected to its previous
and next element. Such data structures are easy to implement as computer memory is
also sequential. Examples of linear data structures are List, Queue, Stack, Array)
elements are stacked on top of each other. Only the last element added can be
accessed, i.e the element at the top of the stack. That is, a stack is a Last In First Out
(LIFO) structure. This is the opposite of a queue which is First in First out (FIFO).
Stack or pile, a structure where insertion and deletion of items takes place at one end
called top of the stack. The basic concept can be illustrated by thinking of your data
set as a stack of plates or books where you can only take the top item of the stack in
order to remove things from it. This structure is used all throughout programming.
The basic implementation of a stack is also called a LIFO (Last In First Out)
Stack is an abstract data type with a bounded(predefined) capacity. It is a simple data
structure that allows adding and removing elements in a particular order. Every time an
element is added, it goes on the top of the stack and the only element that can be removed is
the element that is at the top of the stack, just like a pile of objects.
Basic features of Stack
1. Stack is an ordered list of similar data type.
2. Stack is a LIFO(Last in First out) structure or we can say FILO(First in Last
out).
3. push() function is used to insert new elements into the Stack
and pop() function is used to remove an element from the stack. Both
insertion and removal are allowed at only one end of Stack called Top.
4. Stack is said to be in Overflow state when it is completely full and is said to
be in Underflow state if it is completely empty.
Applications of Stack
The simplest application of a stack is to reverse a word. You push a given word to
stack - letter by letter - and then pop letters from the stack.
There are other uses also like:
Another application is an "undo" mechanism in text editors; this operation is
accomplished by keeping all text changes in a stack.
Language processing:
o space for parameters and local variables is created internally using a
stack.
o compiler's syntax check for matching braces is implemented by using
stack.
o support for recursion
Expression Conversion(Infix to Postfix, Postfix to Prefix etc)
Implementation of Stack Data Structure
Stack can be easily implemented using an Array or a Linked List. Arrays are quick,
but are limited in size and Linked List requires overhead to allocate, link, unlink, and
deallocate, but is not limited in size. Here we will implement Stack using array.
Algorithm for PUSH operation
1. Check if the stack is full or not.
2. If the stack is full, then print error of overflow and exit the program.
3. If the stack is not full, then increment the top and add the element.
Algorithm for POP operation
1. Check if the stack is empty or not.
2. If the stack is empty, then print error of underflow and exit the program.
3. If the stack is not empty, then print the element at the top and decrement the top.
Below we have a simple C++ program implementing stack data structure while following the
object oriented programming concepts.
/* Below program is written in C++ language */
# include<iostream>
using namespace std;
class Stack
int top;
public:
int a[10]; //Maximum size of Stack
Stack()
top = -1;
// declaring all the function
void push(int x);
int pop();
void isEmpty();
};
// function to insert data into stack
void Stack::push(int x)
{
if(top >= 10)
cout << "Stack Overflow \n";
else
a[++top] = x;
cout << "Element Inserted \n";
// function to remove data from the top of the stack
int Stack::pop()
if(top < 0)
cout << "Stack Underflow \n";
return 0;
else
int d = a[top--];
return d;
// function to check if stack is empty
void Stack::isEmpty()
if(top < 0)
cout << "Stack is empty \n";
else
cout << "Stack is not empty \n";
// main function
int main() {
Stack s1;
[Link](10);
[Link](100);
/*
preform whatever operation you want on the stack
*/
Position of Top Status of Stack
-1 Stack is Empty
0 Only one element in Stack
N-1 Stack is Full
N Overflow state of Stack
Analysis of Stack Operations
Below mentioned are the time complexities for various operations that can be performed on
the Stack data structure.
Push Operation : O(1)
Pop Operation : O(1)
Top Operation : O(1)
Search Operation : O(n)
The time complexities for push() and pop() functions are O(1) because we always have to
insert or remove the data from the top of the stack, which is a one step process.
Applications
The simplest two search techniques are known as Depth-First Search(DFS) and
Breadth-First Search (BFS). These two searches are described by looking at how
the search tree (representing all the possible paths from the start) will be traversed.
Deapth-First Search with a Stack
In depth-first search we go down a path until we get to a dead end; then
we backtrack or back up (by popping a stack) to get an alternative path.
Create a stack
Create a new choice point
Push the choice point onto the stack
while (not found and stack is not empty)
o Pop the stack
o Find all possible choices after the last one tried
o Push these choices onto the stack
Return
Breadth-First Search with a Queue
In breadth-first search we explore all the nearest possibilities by finding all
possible successors and enqueue them to a queue.
Create a queue
Create a new choice point
Enqueue the choice point onto the queue
while (not found and queue is not empty)
o Dequeue the queue
o Find all possible choices after the last one tried
o Enqueue these choices onto the queue
Return
We will see more on search techniques later in the course.
Arithmetic Expression Evaluation
An important application of stacks is in parsing. For example, a compiler must
parse arithmetic expressions written using infix notation:
1 + ((2 + 3) * 4 + 5)*6
We break the problem of parsing infix expressions into two stages. First, we
convert from infix to a different representation called postfix. Then we parse the
postfix expression, which is a somewhat easier problem than directly parsing infix.
Now, we describe how to convert from infix to postfix.
1. Read in the tokens one at a time
2. If a token is an integer, write it into the output
3. If a token is an operator, push it to the stack, if the stack is empty. If the
stack is not empty, you pop entries with higher or equal priority and only
then you push that token to the stack.
4. If a token is a left parentheses '(', push it to the stack
5. If a token is a right parentheses ')', you pop entries until you meet '('.
6. When you finish reading the string, you pop up all tokens which are left
there.
7. Arithmetic precedence is in increasing order: '+', '-', '*', '/';
Example. Suppose we have an infix expression:2+(4+3*2+1)/3. We read the
string by characters.
'2' - send to the output.
'+' - push on the stack.
'(' - push on the stack.
'4' - send to the output.
'+' - push on the stack.
'3' - send to the output.
'*' - push on the stack.
'2' - send to the output.
Infix-to-Postfix Conversion using
Stack
Infix, Prefix and Postfix Expressions
1. Infix expression: In this notation, we place operator in the middle of
the operands.
<Operand> <operator> <operand>
2. Prefix expressions: In this notation, we place operator at the
beginning of the
operands.
<Operator> <operand> <operand>
3. Postfix expression: In this notation, we place operator at the end of
the operands.
<Operand> <operand> <operator>
Evaluating a Postfix Expression. We describe how to parse and evaluate a postfix
expression.
1. We read the tokens in one at a time.
2. If it is an integer, push it on the stack
3. If it is a binary operator, pop the top two elements from the stack, apply the
operator, and push the result back on the stack.
Consider the following postfix expression
593+42**7+*
Here is a chain of operations
Stack Operations Output
--------------------------------------
push(5); 5
push(9); 5 9
push(3); 5 9 3
push(pop() + pop()) 5 12
push(4); 5 12 4
push(2); 5 12 4 2
push(pop() * pop()) 5 12 8
push(pop() * pop()) 5 96
push(7) 5 96 7
push(pop() + pop()) 5 103
push(pop() * pop()) 515
Note, that division is not a commutative operation, so 2/3 is not the same as 3/2.