005 - DS Stack

You might also like

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 65

CT - 157

Data Structure Algorithm


& Application ( DSA&A )
Muzammil Ahmad Khan
muzammilkhan@cloud.neduet.edu.pk
1
Books

1. Data Structure: Schaum Outline Series By Seymour Lipschutz

2. A Common-Sense Guide to Data Structures and Algorithms:

By Jay Wengrow

3. Data Structures And Algorithms in Python By Rance Necaise

4. Data Structures And Algorithms in Python By Michael Goodrich

2
Stack

3
Stack

 A stack is an Abstract Data Type (ADT), commonly used in


most programming languages.
 It is named stack as it behaves like a real-world stack,
for example – a deck of cards or a pile of plates, etc

4
Stack

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

5
Stack

• Therefore Stack is a LIFO data structure.


• LIFO stands for Last-In-First-Out.
• Here, the element which is placed (inserted or added) last, is
accessed first. In stack terminology, insertion operation is
called PUSH operation and removal operation is
called POP operation.

6
Stack
 The following diagram depicts a stack and its operations −

7
Stack
 Stack is a LIFO data structure

8
Basic Operations of Stack

 A stack is an object (an abstract data type - ADT) that allows


the following operations:
1. Push: Add an element to the top of a stack
2. Pop: Remove an element from the top of a stack
3. IsEmpty: Check if the stack is empty
4. IsFull: Check if the stack is full
5. Peek: Get the value of the top element without removing it

9
Working of Stack Data Structure
 The operations work as follows:
1. A pointer called TOP is used to keep track of the top element
in the stack.
2. When initializing the stack, we set its value to -1 so that we
can check if the stack is empty by comparing TOP == -1.
3. On pushing an element, we increase the value of TOP and
place the new element in the position pointed to by TOP.
4. On popping an element, we return the element pointed to
by TOP and reduce its value.
5. Before pushing, we check if the stack is already full
6. Before popping, we check if the stack is already empty

10
Working of Stack Data Structure

11
# Stack implementation in Python
# Creating a stack
def create_stack():
stack = []
return stack

# Creating an empty stack


def check_empty(stack):
return len(stack) == 0

# Adding items into the stack


def push(stack, item):
stack.append(item)
print("pushed item: " + item)

# Removing an element from the stack


def pop(stack):
if (check_empty(stack)):
return "stack is empty"

return stack.pop()

stack = create_stack()
push(stack, str(1))
push(stack, str(2))
push(stack, str(3))
push(stack, str(4))
print("popped item: " + pop(stack))
print("stack after popping an element: " + str(stack))

12
Algorithm of isempty function

begin procedure isempty


if top less than 1
return true

else
return false
endif

end procedure

13
Algorithm of isfull function

begin procedure isfull


if top equals to MAXSIZE
return true

else
return false
endif

end procedure

14
Algorithm of peek function

begin procedure peek


return stack[top]
end procedure

15
Algorithm for PUSH Operation

 Push operation involves series of steps

Step 1 − Check if stack is full.


Step 2 − If stack is full, produce error and exit.
Step 3 − If stack is not full, increment top to point next empty
space.

Step 4 − Add data element to the stack location, where top is

pointing.
Step 5 − Return success 16
Algorithm for PUSH Operation

begin procedure push: stack, data


if stack is full
return null

endif
top ← top + 1
stack[top] ← data

end procedure

17
Algorithm for POP Operation

 Accessing the content while removing it from stack, is known


as pop operation.
 In array implementation of pop operation, data element is not
actually removed, instead top is decremented to a lower
position in stack to point to next value.
 But in linked-list implementation, pop actually removes data
element and deallocates memory space.

18
Algorithm for POP Operation

 A POP operation may involve the following steps −

Step 1 − Check if stack is empty.


Step 2 − If stack is empty, produce error and exit.

Step 3 − If stack is not empty, access the data element at which


top is pointing.
Step 4 − Decrease the value of top by 1.
Step 5 − Return success.

19
Algorithm for POP Operation

begin procedure pop: stack


if stack is empty
return null

endif
data ← stack[top]
top ← top - 1

return data
end procedure
20
# Python program for linked list implementation of stack
# Class to represent a node
class StackNode:
# Constructor to initialize a node
def __init__(self, data):
self.data = data
self.next = None
class Stack:
# Constructor to initialize the root of linked list
def __init__(self):
self.root = None
def isEmpty(self):
return True if self.root is None else False
def push(self, data):
newNode = StackNode(data)
newNode.next = self.root
self.root = newNode
print "% d pushed to stack" % (data)
def pop(self):
if (self.isEmpty()):
return float("-inf")
temp = self.root
self.root = self.root.next
popped = temp.data
return popped
def peek(self):
if self.isEmpty():
return float("-inf")
return self.root.data
# Driver code
stack = Stack()
stack.push(10)
stack.push(20)
stack.push(30)

print "% d popped from stack" % (stack.pop())


print "Top element is % d " % (stack.peek())

21
Output:

10 pushed to stack
20 pushed to stack
30 pushed to stack
30 popped from stack
Top element is 20
Elements present in stack : 20 10

22
Application of Stack

 One of the applications of Stack is in the conversion of arithmetic


expressions in high-level programming languages into machine
readable form.
 As our computer system can only understand and work on a
binary language, it assumes that an arithmetic operation can take
place in two operands only e.g., A+B, C*D, D/A etc.
 But in our usual form an arithmetic expression may consist of
more than one operator and two operands
e.g. (A+B)*C(D/(J+D)).
23
Application of Stack

 These complex arithmetic operations can be converted into


polish notation using stacks which then can be executed in
two operands and an operator form.
 Infix Expression
 Postfix Expression

24
Application of Stack
 Infix expression:
The expression of the form a op b. When an operator is in-
between every pair of operands.
It follows the scheme of <operand><operator><operand> i.e.
an <operator> is preceded and succeeded by an <operand>.
Such an expression is termed infix expression. E.g., A+B

 Postfix expression:
The expression of the form a b op. When an operator is
followed for every pair of operands.
It follows the scheme of <operand><operand><operator> i.e.
an <operator> is succeeded by both the <operand>. E.g., AB+
25
Application of Stack

 The compiler scans the expression either from left to right or


from right to left.
 Consider the below expression: a op1 b op2 c op3 d
 If op1 = +, op2 = *, op3 = +
 The compiler first scans the expression to evaluate the
expression b * c, then again scan the expression to add a to it.
The result is then added to d after another scan.
 The repeated scanning makes it very in-efficient. It is better to
convert the expression to postfix(or prefix) form before
evaluation.
26
Application of Stack

 The corresponding expression in postfix form is: abc*+d+.


The postfix expressions can be evaluated easily using a stack.

27
Application of Stack
 Algorithm to convert Infix To Postfix
1. Scan the infix expression from left to right.
2. If the scanned character is an operand, output it.
3. Else,
1 If the precedence of the scanned operator is greater than the precedence of the
operator in the stack(or the stack is empty or the stack contains a ‘(‘ ), push
it.
2 Else, Pop all the operators from the stack which are greater than or equal to in
precedence than that of the scanned operator. After doing that Push the scanned
operator to the stack. (If you encounter parenthesis while popping then stop there
and push the scanned operator in the stack.)
4. If the scanned character is an ‘(‘, push it to the stack.
5. If the scanned character is an ‘)’, pop the stack and and output it until a ‘(‘ is
encountered, and discard both the parenthesis.
6. Repeat steps 2-6 until infix expression is scanned.
7. Print the output 28
8. Pop and output from the stack until it is not empty.
Application of Stack
 Algorithm to convert Infix To Postfix
Let, X is an arithmetic expression written in infix notation. This algorithm finds the equivalent
postfix expression Y.
1. Push “(“onto Stack, and add “)” to the end of X.
2. Scan X from left to right and repeat Step 3 to 6 for each element of X until the Stack is empty.
3. If an operand is encountered, add it to Y.
4. If a left parenthesis is encountered, push it onto Stack.
5. If an operator is encountered ,then:
1. Repeatedly pop from Stack and add to Y each operator (on the top of Stack) which has the same
precedence as or higher precedence than operator.
2. Add operator to Stack.
[End of If]
6. If a right parenthesis is encountered ,then:
1. Repeatedly pop from Stack and add to Y each operator (on the top of Stack) until a left parenthesis is
encountered.
2. Remove the left Parenthesis.
[End of If]
[End of If]
7. END.
29
Infix to Prefix Conversion : Example - 1
Infix: A* B + C

 Infix: A * B + C

30
Infix to Prefix Conversion : Example - 1
Infix: A* B + C
No. Expression Stack Postfix
0 (
1 A ( A
2 ( A
3 * ( * A
4 ( * A
5 B ( * A B
6 ( * A B
7 + ( + A B *
8 ( + A B *
9 C ( + A B * C
10 ) A B * C +

31
Infix to Prefix Conversion : Example - 2
Infix: A* ( B + C )

 Infix: A * ( B + C )

32
Infix to Prefix Conversion : Example - 2
Infix: A* ( B + C )
No. Expression Stack Postfix
0 (
1 A ( A
2 ( A
3 * ( * A
4 ( * A
5 B ( * ( A B
6 ( * ( A B
7 + ( * ( + A B
8 ( * ( + A B
9 C ( * ( + A B C
10 ) ( * A B C+
11 ) A B C+ *

33
Infix to Prefix Conversion : Example - 3
Infix: A*(B+C)/D

 Infix: A * ( B + C ) / D

34
Infix to Prefix Conversion : Example - 3
Infix: A*(B+C)/D
No. Expression Stack Postfix
0 (
1 A ( A
2 * ( * A
3 B ( * ( A B
4 + ( * ( + A B
5 C ( * ( + A B C
6 ) ( * A B C +
7 / ( / A B C + *
8 D ( / A B C + * D
9 ) A B C + * D /

35
Infix to Prefix Conversion : Example - 4
Infix: A* B^C+ D

 Infix: A * B ^ C + D

36
Infix to Prefix Conversion : Example - 4
Infix: A* B^C+ D
No. Expression Stack Postfix
0 ( When the '+' is
1 A ( A encountered in line 6, it is
2 ( A first compared to the '^'
on top of the stack. Since
3 * ( * A
it has lower precedence,
4 ( * A the '^' is popped and
5 B ( * A B printed.
6 ( * A B But instead of pushing
7 the '+' sign onto the stack
^ ( * ^ A B
now, we must compare it
8 ( * ^ A B with the new top of the
9 C ( * ^ A B C stack, the '*'.
10 ( * ^ A B C Since the operator also
11 + ( + A B C ^ * has higher precedence
than the '+', it also must
12 ( + A B C ^ * be popped and printed.
13 D ( + A B C ^ * D Now the stack is empty,
14 ( + A B C ^ * D so the '+' can be pushed
15 ) A B C ^ * D + onto the stack.

37
Infix to Prefix Conversion : Example - 5
Infix: A * ( B + C * D ) + E

 Infix: A * ( B + C * D ) + E

38
Infix to Prefix Conversion : Example - 5
Infix: A * ( B + C * D ) + E
No. Expression Stack Postfix
0 (
1 A ( A
2 ( A
3 * ( * A
4 ( * A
5 B ( * ( A B
6 ( * ( A B
7 + ( * ( + A B
8 ( * ( + A B
9 C ( * ( + A B C
10 ( * ( + A B C
11 * ( * ( + * A B C
12 ( * ( + * A B C
13 D ( * ( + * A B C D
14 ) ( * A B C D * +
15 ( * A B C D * +
16 + ( + A B C D * + *
17 ( + A B C D * + *
18 E ( + A B C D * + * E
19 ( + A B C D * + * E
20 ) A B C D * + * E +
39
Infix to Prefix Conversion : Example - 6
Infix: A+(B*C-(D/E^F)*G)*H

 Infix: A + ( B * C - ( D / E ^ F ) * G ) * H

40
Infix to Prefix Conversion : Example - 6
Infix: A+(B*C-(D/E^F)*G)*H
No. Expression Stack Postfix
0 (
1 A ( A
2 + ( + A
3 B ( + ( A B
4 * ( + ( * A B
5 C ( + ( * A B C
6 - ( + ( - A B C *
7 D ( + ( - ( A B C * D
8 / ( + ( - ( / A B C * D
9 E ( + ( - ( / A B C * D E
10 ^ ( + ( - ( / ^ A B C * D E
11 F ( + ( - ( / ^ A B C * D E F
12 ) ( + ( - A B C * D E F ^ /
13 * ( + ( - * A B C * D E F ^ /
14 G ( + ( - * A B C * D E F ^ / G
15 ) ( + A B C * D E F ^ / G * -
16 * ( + * A B C * D E F ^ / G * -
17 H ( + * A B C * D E F ^ / G * - H
18 ( + * A B C * D E F ^ / G * - H
19 ) A B C * D E F ^ / G * - H * +
41
Infix to Prefix Conversion : Example - 7

 Infix: ( A/(B-C)*D+E)

42
Infix to Prefix Conversion : Example - 7

43
Application of Stack

 Advantage of Postfix Expression over Infix Expression

 An infix expression is difficult for the machine to know and


keep track of precedence of operators. On the other hand, a
postfix expression itself determines the precedence of
operators (as the placement of operators in a postfix
expression depends upon its precedence).
 Therefore, for the machine it is easier to carry out a postfix
expression than an infix expression.
44
Conversion from Infix to Postfix Expression
Step 1: Add '')" to the end of the infix expression
Step 2: Push(onto the stack
Step 3: Repeat until each character in the infix notation is scanned
 IF a(is encountered, push it on the stack
 IF an operand (whether a digit or a character) is encountered, add it postfix expression.
 IF a ")" is encountered, then
a. Repeatedly pop from stack and add it to the postfix expression until a "(" is
encountered.
b. Discard the "(".That is, remove the(from stack and do not add it to the postfix
expression
 IF an operator O is encountered, then
a. Repeatedly pop from stack and add each operator ( popped from the stack) to the
postfix expression which has the same precedence or a higher precedence than O
b. Push the operator to the stack
[END OF IF]
Step 4: Repeatedly pop from the stack and add it to the postfix expression until the stack is empty
Step 5: EXIT
45
Conversion from Infix to Postfix Expression

 Summary of the rules follows:


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

46
# Python program to convert infix expression to postfix

# Class to convert the expression


class Conversion:

# Constructor to initialize the class variables


def __init__(self, capacity):
self.top = -1
self.capacity = capacity
# This array is used a stack
self.array = []
# Precedence setting
self.output = []
self.precedence = {'+':1, '-':1, '*':2, '/':2, '^':3}

# check if the stack is empty


def isEmpty(self):
return True if self.top == -1 else False

# Return the value of the top of the stack


def peek(self):
return self.array[-1]

# Pop the element from the stack


def pop(self):
if not self.isEmpty():
self.top -= 1
return self.array.pop()
else:
return "$"

# Push the element to the stack


def push(self, op):
self.top += 1
self.array.append(op)

# A utility function to check is the given character


# is operand
def isOperand(self, ch):
return ch.isalpha()
47
# Check if the precedence of operator is strictly
# less than top of stack or not
def notGreater(self, i):
try:
a = self.precedence[i]
b = self.precedence[self.peek()]
return True if a <= b else False
except KeyError:
return False

# The main function that


# converts given infix expression
# to postfix expression
def infixToPostfix(self, exp):

# Iterate over the expression for conversion


for i in exp:
# If the character is an operand,
# add it to output
if self.isOperand(i):
self.output.append(i)

# If the character is an '(', push it to stack


elif i == '(':
self.push(i)

# If the scanned character is an ')', pop and


# output from the stack until and '(' is found
elif i == ')':
while( (not self.isEmpty()) and
self.peek() != '('):
a = self.pop()
self.output.append(a)
if (not self.isEmpty() and self.peek() != '('):
return -1
else:
self.pop()
48
# An operator is encountered
else:
while(not self.isEmpty() and self.notGreater(i)):
self.output.append(self.pop())
self.push(i)

# pop all the operator from the stack


while not self.isEmpty():
self.output.append(self.pop())

print "".join(self.output)

# Driver program to test above function


exp = "a+b*(c^d-e)^(f+g*h)-i"
obj = Conversion(len(exp))
obj.infixToPostfix(exp)

49
Queues

 Queue is an abstract data structure, somewhat similar to stack.

 In contrast to stack, queue is opened at both end. One end is


always used to insert data enqueue and the other is used to
remove data dequeue.
 Queue follows First-In-First-Out (FIFO) methodology, i.e.,
the data item stored first will be accessed first.

50
Queues

 A real world example of queue can be a single-lane one-way


road, where the vehicle enters first, exits first. More real-world
example can be seen as queues at ticket windows & bus-stops.

51
Queues

52
Basic Operations of Queues
 Queue operations may involve initializing or defining the
queue, utilizing it and then completing erasing it from
memory. Here we shall try to understand basic operations
associated with queues
1. enqueue − add store an item to the queue.
2. dequeue − remove access an item from the queue.
 Few more functions are required to make above mentioned
queue operation efficient. These are
1. peek − get the element at front of the queue without
removing it.
2. isfull − checks if queue is full.
3. isempty − checks if queue is empty.
53
Algorithm of isempty function

begin procedure isempty


if front is less than MINOR front is greater than rear
return true

else
return false
endif

end procedure

54
Algorithm of isfull function

begin procedure isfull


if rear equals to MAXSIZE
return true

else
return false
endif

end procedure

55
Algorithm of peek function

begin procedure peek


return queue[front]
end procedure

56
enqueue operation
 As queue maintains two data pointers, front and rear, its
operations are comparatively more difficult to implement
than stack.
 The following steps should be taken to enqueue insert data
into a queue
Step 1 − Check if queue is full.
Step 2 − If queue is full, produce overflow error and exit.
Step 3 − If queue is not full, increment rear pointer to point
next empty space.
Step 4 − Add data element to the queue location, where rear is

pointing.
57
Step 5 − return success.
enqueue operation

58
enqueue operation

procedure enqueue(data)
if queue is full
return overflow

endif
rear ← rear + 1
queue[rear] ← data

return true
end procedure
59
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 − return success. 60
dequeue operation

61
dequeue operation

62
Algorithm for dequeue operation

procedure dequeue
if queue is empty
return underflow

end if
data = queue[front]
front ← front - 1

return true
end procedure
63
Algorithm to insert any element in a
queue
Step 1: IF REAR = MAX - 1
Write OVERFLOW
Go to step
[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
64
Algorithm to delete an element from the
queue
Step 1: IF FRONT = -1 or FRONT > REAR
Write UNDERFLOW
ELSE
SET VAL = QUEUE[FRONT]
SET FRONT = FRONT + 1
[END OF IF]
Step 2: EXIT

65

You might also like