You are on page 1of 84

1

CHAPTER FIVE

STACK & QUEUE


3/2/2024 DSA- CH-5: Stack and Queue
CH-5 Contents
2

1. Overview
2. Stacks
3. Queues
4. Deques
5. Priority queues

3/2/2024
CH-5 Contents
3

1. Overview
2. Stacks
3. Queues
4. Deques
5. Priority queues

3/2/2024
Overview
4

 Abstract Data type (ADT) is a type (or class) for


objects whose behavior is defined by a set of value
and a set of operations that are precisely specified
independent of any particular implementation.
 Thus an ADT is an organized collection of information
and a set of operations used to manage that
information.
 The set of operations defines the interface of the ADT. As
long as the ADT fulfills the conditions of the interface, it
doesn’t really matter how the ADT is implemented.

3/2/2024
5

 It is called “abstract” because it gives an implementation


independent view.
 The process of providing only the essentials and hiding the
details is known as abstraction.
 Abstract Data Type as a design tool
 Concerns only on the important concept or model
 No concern on implementation details.

 Stack & Queue is an example of ADT

 An array is not ADT.

3/2/2024
What are the difference?
6

 Stack & Queue vs. Array


 Arrays are data storage structures while stacks and queues
are specialized DS and used as programmer’s tools.
 Stack – a container that allows push and pop
 Queue - a container that allows enqueue and dequeue
 No concern on implementation details.
 In an array any item can be accessed, while in these
data structures access is restricted.
 They are more abstract than arrays.

3/2/2024
CH-5 Contents
7

1. Overview
2. Stacks
3. Queues
4. Deques
5. Priority queues

3/2/2024
Stack
8

 A stack is an Abstract Data Type (ADT), commonly


used in most programming languages.
 Itis named stack as it behaves like a real-world stack,
for example – a deck of cards or a pile of plates, etc.

3/2/2024
9

 A real-world stack allows operations at one end


only.
 For example, we can place or remove a card or plate
from the top of the stack only.
 Likewise, Stack ADT allows all data operations at
one end only.
 At any given time, we can only access the top element
of a stack.

3/2/2024
10

 This feature makes it LIFO data structure.


 LIFO stands for Last-in-first-out. Here, the element
which is placed (inserted or added) last, is accessed
first.
 Stack terminology
 PUSH : insertion operation and
 POP :removal operation

3/2/2024
Basic Operations
11

 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
 push() − Pushing (storing) an element on the stack.
 pop() − Removing (accessing) an element from the stack.
 To use the stack efficiently, we need to check the status
of stack as well.
 peek() − get the top data element of the stack, without
removing it.
 isFull() − check if stack is full.
 isEmpty() − check if stack is empty.

3/2/2024
PUSH Operation
12

 The process of putting a new data element onto


stack is known as a Push Operation.
 Push operation involves a series of steps −
 Step 1 − Checks if the stack is full.
 Step 2 − If the stack is full, produces an error and exit.
 Step 3 − If the stack is not full, increments top to point
next empty space.
 Step 4 − Adds data element to the stack location,
where top is pointing.
 Step 5 − Returns success.

3/2/2024
13

3/2/2024
POP Operation
14

 Accessing the content while removing it from the


stack, is known as a Pop Operation.
 Inan array implementation of pop() operation, the
data element is not actually removed, instead top is
decremented to a lower position in the stack to point to
the next value.
 But in linked-list implementation, pop() actually
removes data element and de-allocates memory space.

3/2/2024
15

 A Pop operation may involve the following steps −


 Step 1 − Checks if the stack is empty.
 Step 2 − If the stack is empty, produces an error and
exit.
 Step 3 − If the stack is not empty, accesses the data
element at which top is pointing.
 Step 4 − Decreases the value of top by 1.

 Step 5 − Returns success.

3/2/2024
16

3/2/2024
Implementation of Stacks
17

 Stack can be implement using


 Arrays (static: the size of stack is given initially)
 Linked lists (dynamic: never become full)

 We will explore implementations based on array


and linked list

3/2/2024
Array implementation of Stack
18

 Called STATIC Stack; data will overflow if you cross the


upper limit of the array.
 Need to declare an array size ahead of time
 Associated with each stack is TopOfStack(TOP)
 For an EMPTYstack, set TopOfStack to -1
◼ Push
◼ (1) Increment TopOfStack by 1.
◼ (2) Set Stack[TopOfStack] = X
◼ Pop
◼ (1) Set return value to Stack[TopOfStack]
◼ (2) Decrement TopOfStack by 1
 These operations are performed in very fast constant
time
3/2/2024
Algorithm for Push
19

 Step-1: Increment the Stack TOP by 1.


 Check whether it is always less than the Upper Limit of
the stack.
 If it is less than the Upper Limit, increment the stack top
by 1 and go to step-2 else report -"Stack Overflow“
 Step-2: Put the new element at the position pointed
by the TOP

3/2/2024
20 3/2/2024
Algorithm for Pop
21

 Step-1: If the Stack is empty then give the alert


"Stack underflow" and quit; or else go to step-2
Step-2:
 a) Hold the value for the element pointed by the TOP
 b) Put a NULL value instead

 c) Decrement the TOP by 1

3/2/2024
22 3/2/2024
Linked List implementation of Stack
23

 Since a dynamic list is used for the stack, the Stack


is also dynamic, means it has no prior upper limit
set.
 So, we don't have to check for the Overflow condition
at all!

3/2/2024
The PUSH Operation
24

 It’s very similar to the insertion operation in a


dynamic singly linked list.
 The only difference is that here you'll add the new
element only at the end of the list, which means
addition can happen only from the TOP.

3/2/2024
25

3/2/2024
Setup EMPTY Stack
26

 Before we implement actual operations, first we


need to setup empty stack.
 First perform the following steps before
implementing actual operations.
 Step 1: Include all the header files which are used in
the program.
 Step 2: Define a Number structure with two
members data and next
 Step 3: Define a Number pointer ‘stack' and ‘top’ and
set it to NULL.

3/2/2024
Algorithm for PUSH
27

 Step 1: Create the newElement to be pushed to the


stack with given value and set newElement →
next as NULL.
 Step 2: Check whether stack is EMPTY
(stack==NULL)
 Step 3: If it is Empty then, set stack = newElement
and top= newElement.
 Step 4: If it is Not Empty then, set top → next=
newElment and top=newElement.
3/2/2024
28

3/2/2024
The POP Operation
29

 This is again very similar to the deletion operation in


any Linked List, but you can only delete from the
end of the list and only one at a time; and that
makes it a stack.
 Here, we'll have a list pointer, "target", which will be
pointing to the last but one element in the List (stack).
Every time we POP, the TOP most element will be
deleted and "target" will be made as the TOP most
element.

3/2/2024
30

3/2/2024
Algorithm for POP
31

 Step 1: Check whether stack is Empty (stack == NULL)


 Step 2: If it is Empty then, display ‘Stack is Empty' and terminate
the function.
 Step 3: If it is Not Empty then, define Number pointer ‘ target ' and
initialize ‘ target' with stack.
 Step 4: Check whether list has only one Node (stack == top)
 Step 5: If it is TRUE. Then, set stack = NULL, top = NULL and
delete top. And terminate the function.
 Step 6: If it is FALSE. Then, move target to its next node. Repeat the
same until it reaches to the top node in the list. (until target→
next == top)
 Step 7: Finally, delete top , Set target → next = NULL and
top=target

3/2/2024
32 3/2/2024
Application of Stacks
33

 Evaluation of algebraic Expression


 1 * (2+3) = 5
 Infix to Postfix conversion
 1 * (2+3) → 123+*
 Balancing Symbol
 To check that every right brace, bracket, and parentheses
must correspond to its left counterpart
◼ e.g. [( )] is legal, but [( ] ) is illegal
 Function Call
 A stack allows a new instance of returning address for each
call to the function

3/2/2024
Application of Stacks: Expression Parsing
34

 The way to write arithmetic expression is known as a


notation.
 An arithmetic expression can be written in three
different but equivalent notations, i.e., without changing
the essence or output of an expression. These notations
are −
◼ InfixNotation
◼ Prefix (Polish) Notation
◼ Postfix (Reverse-Polish) Notation

 These notations are named as how they use


operator in expression.
3/2/2024
35

 Infix Notation
 We write expression in infix notation, e.g. a-b+c, where
operators are used in-between operands.
 It is easy for us humans to read, write, and speak in
infix notation but the same does not go well with
computing devices.
 An algorithm to process infix notation could be difficult
and costly in terms of time and space consumption.

3/2/2024
36

 Prefix Notation
 In this notation, operator is prefixed to operands, i.e.
operator is written ahead of operands.
 For example, +ab. This is equivalent to its infix notation
a+b.
 Prefix notation is also known as Polish Notation.
 Postfix Notation
 This notation style is known as Reversed Polish Notation. In
this notation style, the operator is post fixed to the
operands i.e., the operator is written after the operands.
 For example, ab+. This is equivalent to its infix notation
a+b.

3/2/2024
37

3/2/2024
Parsing Expressions
38

 As we have discussed, it is not a very efficient way


to design an algorithm or program to parse infix
notations.
 Instead, these infix notations are first converted
into either postfix or prefix notations and then
computed.
 To parse any arithmetic expression, we need to take
care of operator precedence and associativity
also.

3/2/2024
Precedence and Associativity
39

3/2/2024
Infix to Postfix Conversion
40

 Step1: Create an empty stack called opstack and


poststack for keeping operators and output
respectively.
 Step2: Convert the input infix string to a list by
using the string method split.
 Step3: Scan the token list from the left to right.
1. If the token is an operand append it to the end of the
poststack
2. If the token is a left parenthesis, push it on the
opstack

3/2/2024
41

3. If the token is a right parenthesis, pop the opstack


until the corresponding left parenthesis is removed.
Append each operator to the end of the poststack .
4. If the token is an operator , *,/,+, or -, push it on the
opstack. However, first remove any operators
already on the opstack that have higher or equal to
precedence and append them to the poststack.
◼ A left parenthesis on the stack will not be removed
unless an incoming right parenthesis is found.

3/2/2024
42

 Step4: When the input expression has been


completely processed, check the opstack. Any
operators still on the stack can be removed and
append to the end of the poststack .

3/2/2024
Example:
43

 Convert the infix expression into postfix expression


E.g.1
◼1*(2+3) ----- 123+*
E.g.2
◼(1+2)*(3+4) --- ?

3/2/2024
Postfix Evaluation Algorithm
44

 Step 1 − Scan the expression from left to right


 Step 2 − If it is an operand push it to stack
 Step 3 − If it is an operator pull operand from
stack and perform operation
 Step 4 − Store the output of step 3, back to stack
 Step 5 − Scan the expression until all operands are
consumed
 Step 6 − Pop the stack and perform operation

3/2/2024
Example
45

 E.g. 1
 InfixExpression : 1*(2+3)
 Postfix expression : 123+*
◼ Result is : 5
 E.g. 2
 InfixExpression : (1+2)*(3+4)
 Postfix expression : 12+34+*
◼ Result is : 21

3/2/2024
CH-5 Contents
46

1. Overview
2. Stacks
3. Queues
4. Deques
5. Priority queues

3/2/2024
Queues
47

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

3/2/2024
Queue Representation
48

 As we now understand that is queue, we access both


ends for different reasons.
 The following diagram given below ties to explain
queue representation as data structure.

3/2/2024
Basic Operation
49

 Queue operations may involve initializing or defining


the queue, utilizing it, and then completely erasing it
from the memory.
 Here we shall try to understand the basic operations
associated with queues −
 enqueue() − add (store) an item to the queue.
 dequeue() − remove (access) an item from the queue.
 peek() − Gets the element at the front of the queue without
removing it.
 isfull() − Checks if the queue is full.
 isempty() − Checks if the queue is empty.

3/2/2024
Enqueue Operation
50

 Queues maintain two data pointers, front and rear.


Therefore, its operations are comparatively difficult to
implement than that of stacks.
 The following steps should be taken to enqueue (insert) data
into a queue
 Step 1 − Check if the queue is full.
 Step 2 − If the queue is full, produce overflow error and exit.
 Step 3 − If the queue is not full, increment rear pointer to point
the next empty space.
 Step 4 − Add data element to the queue location, where the
rear is pointing.
 Step 5 − Return success

3/2/2024
51

3/2/2024
Dequeue Operation
52

 Accessing data from the 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 the queue is empty.
 Step 2 − If the queue is empty, produce underflow error and
exit.
 Step 3 − If the queue is not empty, access the data where front is
pointing.
 Step 4 − Increment front pointer to point to the next available
data element.
 Step 5 − Return success.

3/2/2024
53

3/2/2024
Array implementation of queues
 A queue is a first in, first out (FIFO) data structure
 This is accomplished by inserting at one end (the rear) and
deleting from the other (the front)

 To insert: put new element in location 4, and set rear to 4


 To delete: take element from location 0, and set front to 1
3/2/2024
54
Array implementation of queues
55

 Notice how the array contents “crawl” to the right as


elements are inserted and deleted
 This will be a problem after a while!
3/2/2024
Circular Array
56

3/2/2024
Circular arrays
57

 We can treat the array holding the queue


elements as circular (joined at the ends)

 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;
3/2/2024
Circular Array
58

3/2/2024
Full and empty queues
59

 If the queue were to become completely full, it would


look like this:

 If we were then to remove all eight elements, making


the queue completely empty, it would look like this:

3/2/2024
Full and empty queues: solutions
60

 Solution #1: Keep an additional variable

 Solution #2: (Slightly more efficient) Keep a gap between


elements: consider the queue full when it has n-1 elements

3/2/2024
Linked-list implementation of queues
61

 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

3/2/2024
SLL implementation of queues
62

 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

3/2/2024
Enqueueing a node
63

 To enqueue (add) a node:


 Findthe current last node
 Change it to point to the new last node

 Change the last pointer in the list header

3/2/2024
Dequeueing a node
64

 To dequeue (remove) a node:


 Copy the pointer from the first node into the header

3/2/2024
Queue implementation details
65

 With an array implementation:


 You can have both overflow and underflow
 You should set deleted elements to null

 With a linked-list implementation:


 You can have underflow
 Overflow is a global out-of-memory condition

 There is no reason to set deleted elements to null

3/2/2024
Exercise
66

Operation Content of queue


Enqueue(B)
Enqueue(C)
Dequeue()
Enqueue(G)
Enqueue (F)
Dequeue()
Enqueue(A)
Dequeue()
3/2/2024
CH-5 Contents
67

1. Overview
2. Stacks
3. Queues
4. Deques
5. Priority queues

3/2/2024
Deques
68

 A deque is a double-ended queue


 Insertions and deletions can occur at either end
 Deque has the following basic operations
 EnqueueFront– inserts data at the front of the list
 DequeueFront – deletes data at the front of the list

 EnqueueRear – inserts data at the end of the list

 DequeueRear – deletes data at the end of the list

 Implementation is similar to that for queues


 It is best implemented using doubly linked list
3/2/2024
69

Front Rear

DequeueFront EnqueueFront DequeueRear EnqueueRear

 Deques are not heavily used


 You should know what a deque is, but we won’t
explore them much further.
3/2/2024
CH-5 Contents
70

1. Overview
2. Stacks
3. Queues
4. Deques
5. Priority queues

3/2/2024
Priority Queues
71

 A stack is first in, last out


 A queue is first in, first out
 A priority queue is a queue where each data has
an associated key that is provided at the time of
insertion.
 Itis least-first-out
 The “smallest” element is the first one removed
◼ (You could also define a largest-first-out priority queue)
 The definition of “smallest” is up to the programmer.

3/2/2024
Examples
72

 Consider the following queue of persons where


females have higher priority than males (gender is the
key to give priority).

Abebe Alemu Aster Belay Kedir Meron Yonas

Male Male Female Male Male Female Male

3/2/2024
73

 Dequeue()- deletes Aster


Abebe Alemu Belay Keder Meron Yonas
Male Male Male Male Female Male

 Dequeue()- deletes Meron


Abebe Alemu Belay Kedr Yonas
Male Male Male Male Male
 Now the queue has data having equal priority and dequeue
operation deletes the front element like in the case of ordinary
queues
 Dequeue()- deletes Abebe
Alemu Belay Kedr Yonas
Male Male Male Male 3/2/2024
Priority Queues: Assumptions
74

 The highest priority can be either the minimum


value of all the items, or the maximum.
◼ Wewill assume the highest priority is the
maximum.
 Assume the priority queue has n members

3/2/2024
Operations on Priority Queues
75

 Create: Create a new PQ of a given maximum size


 Add: Add an element to a PQ based on its
priority (key)
 Remove: Remove and return the element in a PQ
with highest priority
 Full: Return whether or not the PQ is full
 Empty: Return whether or not the PQ is empty

3/2/2024
Implementations of Priority Queues
76

Priority
Queue
Implemented as:

Array Linked List Binary Heap

3/2/2024
Array Implementation of Priority
Queues
77

Suppose items with priorities 16, 14, 10, 9, 8, 7, 4, 3, 1


are to be stored in a priority queue.

One implementation:
1 N Max
A 16 14 10 9 8 7 4 3 1

Suppose an item with priority 15 is added:


1 Max
A 16 14 10 9 8 7 4 3 1

15 Thus inserting takes O(N) time: linear


3/2/2024
Linked List Implementation of Priority
78
Queues
L 16 14 10 9 8 7 4 3 1

Suppose an item with priority 2 is to be added:

L 16 14 10 9 8 7 4 3 1

Only O(1) (constant) pointer changes required, but it takes


O(N) pointer traversals to find the location for insertion.

Wanted: a data structure for PQs that can be both searched


and updated in better than O(N) time.
3/2/2024
Demerging and Merging Queues
79

 Demerging Queues
 is the process of creating two or more queues from a
single queue.
 used to give priority for some groups of data
◼ Example: The following two queues can be created from the
below priority queue.

Abebe Alemu Aster Belay Kedir Meron Yonas


Male Mal Female Male Male Female Male

Aster Meron Abebe Alemu Belay Kedir Yonas


Female Female Male Mal Male Male
3/2/2024 Male
Demerging Algorithm
80

create empty females and males queue


while (PriorityQueue is not empty)
{
// delete data at the front
Data=DequeuePriorityQueue();
if(gender of Data is Female)
EnqueueFemale(Data);
else
EnqueueMale(Data);
}

3/2/2024
81

 Merging Queues
 isthe process of creating a priority queue from two or
more queues.
 The ordinary dequeue implementation can be used to
delete data in the newly created priority queue.
◼ Example: The following two queues (females queue has higher
priority than the males queue) can be merged to create a priority
queue.
Aster Meron Abebe Alemu Belay Kedir Yonas
Female Female Male Mal Male Male Male

Aster Meron Abebe Alemu Belay Kedr Yonas


Female Female Male Mal Male 3/2/2024
Male Male
Merging Algorithm
82

create an empty priority queue


while(FemalesQueue is not empty)
{
EnqueuePriorityQueue(DequeueFemalesQueue());
}
while(MalesQueue is not empty)
{
EnqueuePriorityQueue(DequeueMalesQueue());
}
3/2/2024
83

Questions?
3/2/2024
84

Thank You
3/2/2024

You might also like