Professional Documents
Culture Documents
Non-Primitive DS
6
Hence, you can add and remove an element (like, a plate)
only at the topmost position.
C C C
push(M) item = pop()
item = M
R R R
X X X
A A A
7
Working of Stack
Stack works on the LIFO pattern. As we can observe in the below figure
there are five memory blocks in the stack; therefore, the size of the stack
is 5.
Suppose we are storing elements in a stack, and we assume that the stack
is initially empty. We have chosen a stack size of 5, and we are pushing
elements into the stack one by one until it becomes full.
Since our stack is full as the size of the stack is 5. we can observe that it
goes from top to bottom when we were entering the new element in stack.
The stack gets filled up from bottom to the top.
When perform delete operation on stack, there is only one way for entry
and exit as other end is closed. It follows the LIFO pattern, which means
that value entered first will be removed last. value 5 is entered first, so it
will be removed only after the deletion of all the other elements. 8
Working
9
Stack Operations
1. push(): When we insert an element in a stack then the operation is
known as a push. If the stack is full then the overflow condition
occurs.
2. pop(): When we delete an element from the stack, the operation is
known as a pop. If the stack is empty means that no element exists
in the stack, this state is known as an underflow state.
3. isEmpty(): It determines whether the stack is empty or not.
4. isFull(): It determines whether the stack is full or not.'
5. peek(): It returns the element at the given position.
6. count(): It returns the total number of elements available in a stack.
7. change(): It changes the element at the given position.
8. display(): It prints all the elements available in the stack.
10
PUSH operation
11
PUSH
12
POP operation
13
POP operation
14
Peek Operation
15
ARRAY REPRESENTATION OF STACKS
16
If TOP = NULL(-1), then it indicates that the stack is empty
and if TOP = MAX–1, then the stack is full.
(You must be wondering why we have written MAX–1. It is
because array indices start from 0.)
17
Applications of Stack
Balancing of symbols: Stack is used for balancing a symbol.
String reversal: Stack is also used for reversing a string.
UNDO/REDO: It can also be used for performing UNDO/REDO operations.
Recursion: The recursion means that the function is calling itself again. To maintain
the previous states, the compiler creates a system stack in which all the previous
records of the function are maintained.
Backtracking: Suppose we have to create a path to solve a maze problem. If we are
moving in a particular path, and we realize that we come on the wrong way.
Expression conversion: Stack can also be used for expression conversion.
Memory management: The stack manages the memory. The memory is assigned in
the contiguous memory blocks.
18
Expression Evaluation:
All the above expressions have a common structure, i.e., we have an operator
between the two operands. An Operand is an object or a value on which the
operation is to be performed. In the above expressions, 5, 6 are the operands
while '+', '-', and '*' are the operators.
19
20
Infix Notation
When the operator is written in between the operands, then it is known as infix
notation. Operand does not have to be always a constant or a variable; it can
also be an expression itself.
Syntax of infix notation : <operand> <operator> <operand>
If there is only one operator in the expression, we do not require applying any
rule. For example, 5 + 2; in this expression, addition operation can be
performed between the two operands (5 and 2), and the result of the operation
would be 7.
If there are multiple operators in the expression, then some rule needs to be
followed to evaluate the expression.
If the expression is: 4 + 6 * 2
If plus operator is evaluated first, then expression: 10 * 2 = 20
If the multiplication operator is evaluated first, then the expression would look
21
like: 4 + 12 = 16
Operator precedence
The above problem can be resolved by following the operator precedence rules. In
the algebraic expression, the order of the operator precedence is given in the
below table:
Operators Symbols
Parenthesis ( ), {}, [ ]
Exponents ^
Multiplication and Division *, /
Addition and Subtraction +,-
22
Operator Precedence
23
Operator precedence
The first preference is given to the parenthesis; then next preference is given to the
exponents. In the case of multiple exponent operators, then the operation will be applied
from right to left
For example: 2^2^3 = 2 ^ 8 = 256
After exponent, multiplication, and division operators are evaluated. If both the operators
are present in the expression, then the operation will be applied from left to right.
The next preference is given to addition and subtraction. If both the operators are
available in the expression, then we go from left to right.
The operators that have same precedence term as operator associativity. If we go from
left to right, then it is known as left-associative. If we go from right to left, then it is
known as right-associative.
Follow the order of operations (PEMDAS/BODMAS), which stands for
Parentheses/Brackets, Exponents/Orders (i.e., powers and square roots, etc.),
Multiplication and Division (left-to-right), and Addition and Subtraction (left-to-right).
24
Postfix Expression
Postfix notation is also known as Reverse Polish Notation (RPN), and it's a
way of representing mathematical expressions that eliminates the need for
parentheses and follows a specific order of operations.
The postfix expression is an expression in which the operator is written after
the operands. For example, the postfix expression of infix notation ( 2+3) can
be written as 23+.
Some key points regarding the postfix expression are:
In postfix expression, operations are performed in the order in which they
have written from left to right.
It does not require any parenthesis.
We do not need to apply operator precedence rules and associativity rules.
25
Evaluation of postfix expression using stack
26
Example 1: Postfix expression: 2 3 4 * +
Input Stack
29
Algorithm to convert Infix to Postfix
Here's a step-by-step algorithm for converting an infix expression to postfix:
1. Initialize an empty stack and an empty output list (Post 10. Token ( (open parenthesis) goes to the stack.
Fix). 11. Token 1 (operand) goes to the output list.
2. Start scanning the infix expression from left to right. 12. Token - (operator) has lower precedence than '/', so it
3. Token 3 (operand) goes to the output list. goes to the stack.
4. Token + (operator) goes to the stack. 13. Token 5 (operand) goes to the output list.
5. Token 4 (operand) goes to the output list. 14. Token ‘)’ (close parenthesis) causes the stack to pop '-'
6. Token * (operator) has higher precedence than '+', so it and added it to the output list, and ‘(‘ and ‘)’ is discarded.
goes to the stack. 15. Finally, pop '/' and add it to the output list.
7. Token 2 (operand) goes to the output list. 16. After scanning the entire expression, pop any
8. Token / (operator) has the same precedence as '', so '' is remaining operators from the stack and add them to the
popped and added to the output list, then '/' goes to the output list. In this case, '+' is the only remaining operator.
stack.
31
• The resulting postfix expression is: 3 4 2 * 1
infix expression : "a + b * c - d":
32
• The resulting postfix expression is:
33
34
Solve example Infix to postfix
Infix Postfix
A+B AB+
A+B-C AB+C-
(A+B)*(C-D) AB+CD-*
35
Prefix notation
37
Algorithm for conversion of infix to prefix expression
38
39
Solve example Infix to prefix
(a) A – B + C
(b) A * B + C / D
(c) (A – B ) + C * D / E – C
(d) (A * B) + (C / D) – ( D + E)
(e) ((A – B) + D / ((E + F) * G))
(f) ( A – 2 * (B + C) / D * E) + F
(g) 14 / 7 * 3 – 4 + 9 / 2
40
Queue
Queue is an abstract data structure, somewhat similar to
Stacks. Unlike stacks, a queue is open at both its ends.
One end is always used to insert data (enqueue) and the
other is used to remove data (dequeue).
Queue follows First-In-First-Out methodology, i.e., the
data item stored first will be accessed first.
41
The concept of queues using the analogies given below
1) people moving on an escalator. The people who got on the escalator
first will be the first one To step out of it.
2) people waiting for a bus. The first person standing in the line will be
the first one to get into The bus.
3) people standing outside the ticketing window of a cinema hall. The first
person in the line Will get the ticket first and thus will be the first one to
move out of it.
4) luggage kept on conveyor belts. The bag which was placed first will be
the first to come out At the other end.
5) cars lined at a toll bridge. The first car to reach the bridge will be the
first to leave. 42
Queue
43
Here, front = 0 and rear = 5. If we want to add one more value to the
list, say, if we want to add another element with the value 45, then the
rear would be incremented by 1 and the value would be stored at the
position pointed by the rear.
After inserting, front = 0 and rear = 6. Every time a new element is to be
added, we will repeat the same procedure.
44
Now, if we want to delete an element from the queue, then the value of front will be
incremented.
Deletions are done only from front end of the queue. However, before inserting an element
in the queue, we must check for overflow conditions. An overflow occurs when try to insert
an element into a queue that is already full. A queue is full
when rear = MAX – 1, where MAX is the size of the queue, that is MAX specifies the
maximum number of elements in the queue. Note that we have written MAX – 1 because the
index starts from 0.
Similarly, before deleting an element from the queue, we must check for underflow
conditions.
An underflow condition occurs when we try to delete an element from a queue that is
already empty. If front = NULL and rear = NULL, then there is no element in the queue. 45
Operation on Queue
46
Operation on Queue
47
Algorithm to insert element in queue
Step 1: IF REAR = MAX-1 Write OVERFLOW
Goto step 4
[END OF IF]
Step 2: IF FRONT = -1 and REAR = -1 SET FRONT = REAR = 0
ELSE
SET REAR = REAR + 1
[END OF IF]
Step 3: SET QUEUE[REAR] = NUM
Step 4: EXIT
48
Insertion Algorithm
In Step 1, we first check for the overflow condition.
In Step 2, we check if the queue is empty. In case the queue is
empty, then both FRONT and REAR are set to zero, so that the new
value can be stored at the 0th location.
Otherwise, if the queue already has some values, then REAR is
incremented so that it points to the next location in the array.
In Step 3, the value is stored in the queue at the location pointed by
REAR.
49
Insert element in queue
Before inserting an element in a queue, we must check
for overflow conditions.
An overflow will occur when we try to insert an element
into a queue that is already full.
When rear = max – 1, where max is the size of the queue,
we have an overflow condition.
Note that we have written max – 1 because the index
starts from 0.
50
Algorithm to delete an element from a queue
Step 1: IF
FRONT = -1
OR
FRONT > REAR
Write UNDERFLOW
Else
Set Front = Front + 1
[End Of If]
Step 2: EXIT
51
Deletion Algorithm
The algorithm to delete an element from a queue.
In step 1, we check for underflow condition.
An underflow occurs if front = –1 or front > rear. However,
If queue has some values, then FRONT is incremented so that it now
points to the next value in the queue.
52
Delete an element from a queue
53
Queue Operation Summery
54
Applications of Queue
55
Types of queues
A queue data structure can be classified into the
following types:
Circular Queue
Deque (double ended queue)
Priority Queue
56
Circular Queue
57
The circular Queue can be used in the following scenarios:
Memory management: The circular queue provides memory management. As
we have already seen that in linear queue, the memory is not managed very
efficiently. But in case of a circular queue, the memory is managed efficiently by
placing the elements in a location which is unused.
CPU Scheduling: The operating system also uses the circular queue to insert the
processes and then execute them.
Traffic system: In a computer-control traffic system, traffic light is one of the
best examples of the circular queue. Each light of traffic light gets ON one by
one after every j interval of time. Like red light gets ON for one minute then
yellow light for one minute and then green light. After green light, the red light
gets ON.
58
Circular Queue
In linear queues, we have discussed so far that insertions can be done only at one
end called the REAR and deletions are always done from the other end called the
FRONT. Look at the queue shown in Fig. 8.13.
59
Consider a scenario in which two successive deletions are made. The queue will then be
given as shown in Fig. 8.14. Here, front = 2 and REAR = 9.
Suppose we want to insert a new element in the queue shown in Fig. 8.14. Even though
there is space available, the overflow condition still exists because the condition rear =
MAX – 1 still holds true.
This is a major drawback of a linear queue.
To resolve this problem, two solutions. First, shift the elements to the left so that vacant
space can be occupied and utilized efficiently. But this can be very time consuming,
especially when the queue is quite large.
The second option is to use a circular queue. In the circular queue, the first index comes
60
right after the last index.
The circular queue will be full only when front = 0 and rear = Max – 1.
A circular queue is implemented in the same manner as a linear queue
is implemented.
The only difference will be in the code that performs insertion and
deletion operations.
61
Insertion on circular queue
For insertion check for the following three conditions:
1. If front = 0 and rear = MAX – 1, then the circular queue is full. Look at
the queue given in Fig. 8.16
62
2. If rear != MAX – 1, then rear will be incremented and the value will
be inserted as illustrated in Fig.
63
3. If front != 0 and rear = MAX – 1, then it means that the queue is not
full. So, set rear = 0 and insert the new element there, as shown in Fig.
64
Algorithm for insertion
65
Algorithm for insertion
66
Deletion on circular queue
1.Look at Fig. 8.20. If front = –1, then there are no elements in the queue. So,
an underflow condition will be reported.
67
2. If the queue is not empty and front = rear, then after deleting the
element at the front the queue becomes empty and so front and rear
are set to –1. This is illustrated in Fig. 8.21.
68
3. If the queue is not empty and front = MAX–1, then after deleting the
element at the front, front is set to 0. This is shown in Fig. 8.22.
69
Algorithm for Deletion
70
Algorithm for Deletion
The algorithm to delete an element from a circular queue.
In Step 1, we check for the underflow condition.
In Step 2, the value of the queue at the location pointed by FRONT is
stored in VAL.
In Step 3, checks. First to see if the queue has become empty after
deletion and second to see if FRONT has reached the maximum
capacity of the queue. The value of FRONT is then updated based on
the outcome of these checks.
71
Double Ended Queue (Deque)
The deque stands for Double Ended Queue.
Deque is a linear data structure where the insertion and deletion operations are
performed from both ends. No element can be added and deleted from the
middle.
deque is a generalized version of the queue.
Though the insertion and deletion in a deque can be performed on both ends, it
does not follow the FIFO rule.
The representation of a deque is given as follows –
72
Types of deque
73
Input restricted Queue
In input restricted queue, insertion operation can be performed at
only one end, while deletion can be performed from both ends.
74
Output restricted Queue
75
Operations on deque
76
Insertion at the front end
In this operation, the element is inserted from the front end of the
queue. Before implementing the operation, we first have to check
whether the queue is full or not. If the queue is not full, then the
element can be inserted from the front end by using the below
conditions -
If the queue is empty, both rear and front are initialized with 0. Now,
both will point to the first element.
Otherwise, check the position of the front if the front is less than 1
(front < 1), then reinitialize it by front = n - 1, i.e., the last index of the
array.
77
Insertion at the front end
78
Insertion at the rear end
In this operation, the element is inserted from the rear end of the
queue. Before implementing the operation, we first have to check
again whether the queue is full or not. If the queue is not full, then the
element can be inserted from the rear end by using the below
conditions –
If the queue is empty, both rear and front are initialized with 0. Now,
both will point to the first element.
Otherwise, increment the rear by 1. If the rear is at last index (or size -
1), then instead of increasing it by 1, we have to make it equal to 0.
79
Insertion at the rear end
80
Deletion at the front end
In this operation, the element is deleted from the front end of the queue. Before
implementing the operation, we first have to check whether the queue is empty
or not.
If the queue is empty, i.e., front = -1, it is the underflow condition, and we
cannot perform the deletion. If the queue is not full, then the element can be
deleted from the front end by using the below conditions -
If the deque has only one element, set rear = -1 and front = -1.
Else if front is at end (that means front = size - 1), set front = 0.
Else increment the front by 1, (i.e., front = front + 1).
81
Deletion at the front end
82
Deletion at the rear end
In this operation, the element is deleted from the rear end of the queue.
Before implementing the operation, we first have to check whether the queue
is empty or not.
If the queue is empty, i.e., front = -1, it is the underflow condition, and we
cannot perform the deletion.
If deque has only one element set rear = -1 and front = -1.
If rear = 0 (rear is at front), then set rear = n - 1.
Else, decrement the rear by 1 (or, rear = rear -1).
83
Deletion at the rear end
84
Check empty: This operation is performed to check whether the deque is empty
or not. If front = -1, it means that the deque is empty.
Check full: This operation is performed to check whether the deque is full or
not. If front = rear + 1, or front = 0 and rear = n - 1 it means that the deque is
full. The time complexity of all of the above operations of the deque is O(1),
i.e., constant.
Applications of deque
Deque can be used as both stack and queue, as it supports both operations.
Deque can be used as a palindrome checker means that if we read the string
from both ends, the string would be the same.
85
Priority Queue
A priority queue is a data structure in which each element is assigned a
priority.
The priority of the element will be used to determine the order in
which the elements will be processed.
The general rules of processing the elements of a priority queue are An
element with higher priority is processed before than an element with a
lower priority.
Two elements with the same priority are processed on a first-come-
first-served (FCFS) basis.
86
Types of Priority Queue
There are two types of priority queue:
Ascending order priority queue: In ascending order priority queue, a
lower priority number is given as a higher priority in a priority. For
example, we take the numbers from 1 to 5 arranged in an ascending order
like 1,2,3,4,5; therefore, the smallest number, i.e., 1 is given as the highest
priority in a priority queue.
87
Descending order priority queue: In descending order priority queue, a
higher priority number is given as a higher priority in a priority. For example,
we take the numbers from 1 to 5 arranged in descending order like 5, 4, 3, 2,
1; therefore, the largest number, i.e., 5 is given as the highest priority in a
priority queue.
88
Operations
In function insert_element(), initially check if the queue is full. If it is,
then print the result as "Queue Overflow". If not, take the number to be
inserted as input and insert a new element into the priority queue.
In the function delete_element(), firstly check if the queue is empty. If
it is, then print the result as "Queue Underflow". Otherwise, remove
the element and the priority from the front of the queue.
In the function display_priorityqueue(), using for loop print all the
elements of the queue starting from front to rear.
The function check_priority() is used to check the priority and place
element.
89
Applications Of The Priority Queue
The following are the applications of the priority queue:
It is used in the Dijkstra's shortest path algorithm.
It is used in prim's algorithm
It is used in data compression techniques like Huffman code.
It is used in heap sort.
It is also used in operating system like priority scheduling, load
balancing and interrupt handling.
90
THANKS!
Any questions?
+91-8087079707
vinay.patil@adypu.edu.in
91