STACK
STACK
3
Stack ADT Interface
The main functions in the Stack ADT are (S is the stack)
5/4/2022 CS 201
Axioms
5
What is a Stack?
➢A stack is an Abstract Data Type (ADT),
commonly used in most programming
languages.
➢ A Stack is a linear data structure that
follows the LIFO (Last-In-First-
Out) principle.
➢ It contains only one pointer top
pointer pointing to the topmost element
of the stack.
What is a Stack?
➢ Whenever an element is added in the
stack, it is added on the top of the stack,
and the element can be deleted only
from the stack.
Stack Representation
10
push
pop
create
STACK
isempty
isfull
11
STACK: Last-In-First-Out (LIFO)
•void push (stack *s, int element);
/* Insert an element in the stack */
•int pop (stack *s);
/* Remove and return the top element
*/
•void create (stack *s);
/* Create a new stack */
•int isempty (stack *s);
/* Check if stack is empty */
•int isfull (stack *s);
/* Check if stack is full */
Assumption: stack contains integer elements!
12
Array implementation of stacks
To implement a stack, items are inserted and removed at
the same end (called the top)
Efficient array implementation requires that the top of the
stack be towards the center of the array, not fixed at one
end
To use an array to implement a stack, you need both the
array itself and an integer
The integer tells you either:
Which location is currently the top of the stack, or
How many elements are in the stack
13
Pushing and popping
0 1 2 3 4 5 6 7 8 9
stk:
17 23 97 44
top = 3 or count = 4
14
After popping
0 1 2 3 4 5 6 7 8 9
stk:
17 23 97 44
top = 2 or count = 3
15
Error checking
There are two stack errors that can occur:
Underflow: trying to pop (or peek at) an empty stack
Overflow: trying to push onto an already full stack
For underflow, you should throw an exception
If you don’t catch it yourself, Java will throw an ArrayIndexOutOfBounds
exception
You could create your own, more informative exception
For overflow, you could do the same things
Or, you could check for the problem, and copy everything into a new, larger
array
16
Linked-list implementation of
stacks
Since all the action happens at the top of a stack, a singly-
linked list (SLL) is a fine way to implement it
The header of the list points to the top of the stack
myStack:
44 97 23 17
17
Linked-list implementation details
With a linked-list representation, overflow will not
happen (unless you exhaust memory, which is
another kind of problem)
Underflow can happen, and should be handled the
same way as for an array implementation
When a node is popped from a list, and the node
references an object, the reference (the pointer in the
node) does not need to be set to null
Unlike an array implementation, it really is removed--you can no longer get to
it from the linked list
Hence, garbage collection can occur as appropriate
18
Basic Operations
➢ Stack operations may involve initializing
the stack, using it and then de-initializing
it. Apart from these basic stuffs, a stack
is used for the following two primary
operations −
a. push() − Pushing (storing) an
element on the stack.
b. pop() − Removing (accessing) an
element from the stack.
Basic Operations
➢ To use a stack efficiently, we need to
check the status of stack as well. For the
same purpose, the following
functionality is added to stacks −
a. peek() − get the top data element of
the stack, without removing it.
b. isFull() − check if stack is full.
c. isEmpty() − check if stack is empty.
Stack using Array
21
Push using Stack
PUSH
top
top
22
Pop using Stack
POP
top
top
23
Stack using Linked List
24
Push using Linked List
PUSH OPERATION
top
POP OPERATION
top
26
Basic Idea
•In the array implementation, we would:
•Declare an array of fixed size (which determines the maximum size
of the stack).
•Keep a variable which always points to the “top” of the stack.
•Contains the array index of the “top” element.
27
Declaration
28
Stack Creation
29
Push Operation
The process of putting a new data element onto stack is known
as a Push Operation. Push operation involves a series of steps −
31
Pushing an element into stack
Algorithm to push an element into stack− Array
32
Pushing an element into stack
Algorithm to push an element into stack− Linked List
33
Pushing an element into stack
void push (stack *s, int element) void push (stack **top, int element)
{ {
stack *new;
if (s->top == (MAXSIZE-1))
{ new = (stack *)malloc (sizeof(stack));
printf (“\n Stack overflow”); if (new == NULL)
exit(-1); {
} printf (“\n Stack is full”);
exit(-1);
else
}
{
s->top++; new->value = element;
s->st[s->top] = element; new->next = *top;
} *top = new;
}
}
36
Popping an element from stack
37
Popping an element from stack
38
Popping an element from stack
int peek()
{
return stack[top];
}
Checking for Stack Full
Algorithm of isfull() function −
42
Checking for stack empty
Algorithm of isempty() function −
44
Application of Stack Data Structure
•Stack is used for expression evaluation
•Stack is used for parenthesis matching while working
with expressions.
• Stack is used in expression conversion. For example,
infix to postfix or prefix to postfix
•Stack is used in memory management
• It is used in java virtual machine
• It is used for the Backtracking problem-solving method
Application of Stack Data Structure
•It is used in string parsing or string reversal.
•Stack is used to matching the HTML tags in web
development
•Stack is also used in function call for recursive
functions.
Applications of Stacks
•Direct applications:
•Page-visited history in a Web browser
•Undo sequence in a text editor
•Chain of method calls in the Java Virtual Machine
•Validate XML
•Indirect applications:
•Auxiliary data structure for algorithms
•Component of other data structures
47
48
Partial Table of Operator Precedence and
Associativity
Operator Associativity
* / % left to right
+ - left to right
= += -= right to left
Operators on the top line have the highest precedence.
Precedence decreases line-by-line going down the table.
All operators on the same line have equal precedence.
49
Infix and Postfix Notations
•Infix: operators placed between operands:
A+B*C
•Postfix: operands appear before their operators:-
ABC*+
•There are no precedence rules to learn in postfix notation, and
parentheses are never needed
50
Infix to Postfix
Infix Postfix
A+B AB+
A+B*C ABC*+
(A + B) * C AB+C*
A+B*C+D ABC*+D+
(A + B) * (C + D) AB+CD+*
A*B+C*D AB*CD*+
A + B * C → (A + (B * C)) → (A + (B C *) ) → A B C * +
52
Evaluation of postfix expression -
53
Evaluation of postfix expression -
54
Infix to postfix conversion
•Use a stack for processing operators (push and pop
operations).
•Scan the sequence of operators and operands from left to right
and perform one of the following:
•output the operand,
•push an operator of higher precedence,
•pop an operator and output, till the stack top contains operator of a lower precedence
and push the present operator.
55
The algorithm steps
1. Print operands as they arrive.
2. If the stack is empty or contains a left parenthesis on top, push the incoming
operator onto the stack.
3. If the incoming symbol is a left parenthesis, push it on the stack.
4. If the incoming symbol is a right parenthesis, pop the stack and print the
operators until you see a left parenthesis. Discard the pair of parentheses.
5. If the incoming symbol has higher precedence than the top of the stack, push it
on the stack.
6. If the incoming symbol has equal precedence with the top of the stack, use
association. If the association is left to right, pop and print the top of the stack
and then push the incoming operator. If the association is right to left, push the
incoming operator.
7. If the incoming symbol has lower precedence than the symbol on the top of the
stack, pop the stack and print the top operator. Then test the incoming operator
against the new top of stack.
8. At the end of the expression, pop and print all operators on the stack. (No
parentheses should remain.)
56
Infix to Postfix Conversion
Requires operator precedence information
Operands:
Add to postfix expression.
Close parenthesis:
pop stack symbols until an open parenthesis appears.
Operators:
Pop all stack symbols until a symbol of lower precedence appears.
Then push the operator.
End of input:
Pop all remaining stack symbols and add to the expression.
57
Infix to Postfix Conversion
58
Infix to Postfix Conversion
59
Example - Conversion Infix to Postfix
60
Example - Conversion Infix to Postfix
61
Queue
62
What is a queue?
It is an ordered group of homogeneous items of
elements.
Queues have two ends:
Elements are added at one end.
Elements are removed from the other end.
The element added first is also removed first
(FIFO: First In, First Out).
Queue
Elements of queue:-
Front
Rear
array
Basic Operations
❖ Queue operations may involve initializing or defining the
queue, utilizing it and then completing erasing it from
memory.
• Operations
– MakeEmpty
– Boolean IsEmpty
– Boolean IsFull
– Enqueue (ItemType newItem)
– Dequeue (ItemType& item)
Peek ()
a. This function helps to see the data at the front of the
queue. Algorithm of peek function − .
return queue[front]
end procedure
a. Implementation of peek function in C programming language
int peek()
{
return queue[front];
}
isfull()
a. As we are using single dimension array to implement
queue, we just check for the rear pointer to reach at
MAXSIZE to determine that queue is full. In case we
maintain queue in a circular linkedlist, the algorithm
will differ. Algorithm of isfull function −
begin procedure isfull
if rear equals to MAXSIZE
return true
else
return false
endif
end procedure
isfull()
a. Implementation of isfull function in C programming language
bool isfull()
{
if(rear == MAXSIZE - 1)
return true;
else
return false;
}
isempty()
a. Algorithm of isempty function−
begin procedure isempty
if front is less than MIN OR front is greater than rear
return true
else
return false
endif
end procedure
bool isempty()
{
if(front < 0 || front > rear)
return true;
else
return false;
}
Enqueue (ItemType newItem)
As queue maintains two data pointers, front and rear,
its operations are comparatively more difficult to
implement than stack.
rear = rear + 1;
queue[rear] = data;
return 1;
end procedure
Dequeue (ItemType& item)
Function: Removes front item from queue and returns it in
item.
Preconditions: Queue has been initialized and is not empty.
Postconditions: Front element has been removed from
queue and item is a copy of removed element.
Dequeue Operation
Accessing data from queue is a process of two tasks − access
the data where front is pointing and remove the data after
access. The following steps are taken to perform dequeue
operation −
❖ Step 1 − Check if queue is empty.
❖ Step 2 − If queue is empty, produce underflow error and exit.
❖ Step 3− − If queue is not empty, access data where front is
pointing.
❖ Step 4 − − Increment front pointer to point next available data
element.
❖ Step 5 − Returns success.
Dequeue Operation
Algorithm for dequeue operation
Enqueue Operation
Implementation of enqueue in C programming language −
int dequeue()
{
if(isempty())
return 0;
0 1 2 3 4 5 6 7
myQueue:
17 23 97 44
front = 0 rear = 3
93
Array implementation of queues
front = 0 rear = 3
Initial queue: 17 23 97 44
front = 1 rear = 4
0 1 2 3 4 5 6 7
myQueue:
44 55 11 22 33
rear = 1 front = 5
Elements were added to this queue in the order 11, 22, 33,
44, 55, and will be removed in the same order
Use: front = (front + 1) % myQueue.length;
and: rear = (rear + 1) % myQueue.length;
95
Full and empty queues
If the queue were to become completely full, it would look
like this:
0 1 2 3 4 5 6 7
myQueue:
44 55 66 77 88 11 22 33
rear = 4 front = 5
0 1 2 3 4 5 6 7
myQueue:
rear = 4 front = 5
This is a problem! 96
Full and empty queues: solutions
Solution #1: Keep an additional variable
0 1 2 3 4 5 6 7
myQueue:
44 55 66 77 88 11 22 33
0 1 2 3 4 5 6 7
myQueue:
44 55 66 77 11 22 33
rear = 3 front = 5
97
Linked-list implementation of queues
In a queue, insertions occur at one end, deletions at the
other end
Operations at the front of a singly-linked list (SLL) are
O(1), but at the other end they are O(n)
Because you have to find the last element each time
BUT: there is a simple way to use a singly-linked list to
implement both insertions and deletions in O(1) time
You always need a pointer to the first thing in the list
You can keep an additional pointer to the last thing in the list
98
SLL implementation of queues
In an SLL you can easily find the successor of a node,
but not its predecessor
Remember, pointers (references) are one-way
If you know where the last node in a list is, it’s hard to
remove that node, but it’s easy to add a node after it
Hence,
Use the first element in an SLL as the front of the queue
Use the last element in an SLL as the rear of the queue
Keep pointers to both the front and the rear of the SLL
99
Enqueueing a node
Node to be
last enqueued
first
44 97 23 17
100
Dequeueing a node
last
first
44 97 23 17
101
Queue implementation details
With an array implementation:
you can have both overflow and underflow
you should set deleted elements to null
102
‘Queue Full(Overflow)’ Condition
Queue Full(Overflow):
Inserting an element in a queue which is already full is known as Queue
Full condition (Rear = Max-1).
When the queue is fully occupied and enqueue() operation is called
queue overflow occurs.
Queue Empty:
Deleting an element from queue which is already empty is known as
Queue Empty condition (Front = Rear = -1)
When the queue is fully empty and dequeue() operation is called
queue underflow occurs.
Queue Empty:
Before deleting any element from queue check whether there is an
element in the queue. If no element is present inside a queue & front
& rear is set to -1 then queue is said to be empty.
Size of queue = 4
Front = Rear = -1
Disadvantages of linear queue
On deletion of an element from existing
queue, front pointer is shifted to next
position.
This results into virtual deletion of an
element.
By doing so memory space which was
occupied by deleted element is wasted and
hence inefficient memory utilization is
occur.
Overcome disadvantage of linear queue:
1. Circular Queue
3. Priority Queue
CIRCULAR QUEUE
A queue, in which the last node is connected back to the
first node to form a cycle, is called as circular queue.
Circular queue are the queues implemented in circular
form rather than in a straight line.
Circular queues overcome the problem of unutilized
space in linear queue implemented as an array.
The main disadvantage of linear queue using array is that
when elements are deleted from the queue, new elements
cannot be added in their place in the queue, i.e. the
position cannot be reused.
CIRCUL
AR
QUEUE
CIRCULAR QUEUE IMPLEMENTATION
The stack is based on LIFO(Last In First Out) The queue is based on FIFO(First In First Out)
principle principle.
Insertion Operation is called Push Operation Insertion Operation is called Enqueue Operation
Deletion Operation is called Pop Operation Deletion Operation is called Dequeue Operation
Push and Pop Operation takes place from one Enqueue and Dequeue Operation takes place
end of the stack from a different end of the queue
The most accessible element is called Top and The insertion end is called Rear End and the
the least accessible is called the Bottom of the deletion end is called the Front End.
stack
Simple Implementation Complex implementation in comparison to
stack
Only one pointer is used for performing Two pointers are used to perform operations
operations
Difference between Stack & Queue
Stack Queue
Used to solve the recursive type problems Used to solve the problem having sequential
processing
THANK YOU