0% found this document useful (0 votes)
26 views133 pages

CSE 220 Week 5

Uploaded by

ohidul.hossain
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views133 pages

CSE 220 Week 5

Uploaded by

ohidul.hossain
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 133

Data Structures

Mushtari Sadia
Stack
Introduction
Basic Operations
● Push(obj): adds obj to the top of the stack ("overflow" error if the stack has fixed capacity,
and is full)

● Pop: removes and returns the item from the top of the stack ("underflow" error if the stack
is empty)

● Peek: returns the item that is on the top of the stack, but does not remove it ("underflow"
error if the stack is empty)
Stack

Fixed capacity - implemented with array Unlimited capacity - implemented with linked list
Fixed Capacity Stack Example

Create (Implemented with array)

Stack of
Size 4
Push(1)

1
Push(2)

1
Push(3)

1
Push(4)
4

1
Push(5) Stack Overflow Error!

1
Peek
4

Will return 4, but will not


2 remove 4 from the stack

1
Pop
4

Will return 4 and remove


2 4 from the stack

1
Pop

1
Pop

1
Pop

1
Pop Stack Underflow Error!
import numpy as np

class Stack:
def __init__(self):
self.stack = np.zeros(4, dtype=int) Code
Implementing The
self.top = -1

def push(self, item):


if self.top == len(self.stack) - 1: Structure with
else:
print("Stack overflow")
Array
self.top += 1
self.stack[self.top] = item
def peek(self):
def pop(self): if self.top == -1:
if self.top == -1: print("Stack is empty")
print("Stack underflow") else:
else: return self.stack[self.top]
item = self.stack[self.top]
self.stack[self.top] = None
self.top -= 1
return item
stack = Stack()
stack.push(1)
Driver Code
stack.push(2) Using the
stack.push(3)
stack.push(4)
implemented
stack.push(5) structure
print(stack.peek())
print(stack.pop())
stack.pop()
print(stack.pop())
stack.pop()
stack.pop()
Fixed Capacity Stack Example
top = -1
Driver code:

Create stack = Stack()

Stack of Code running

Size 4 behind the scene:


def __init__(self):
self.stack = np.zeros(4, dtype=int)
self.top = -1
Driver code:

Push(1) top = 0
stack.push(1)

Code running
behind the scene:

def push(self, item):


if self.top == len(self.stack) - 1:
print("Stack overflow")
else:
self.top += 1
1 self.stack[self.top] = item
Driver code:

Push(2) top = 1
stack.push(2)

Code running
behind the scene:

def push(self, item):


if self.top == len(self.stack) - 1:
2
print("Stack overflow")
else:
self.top += 1
1 self.stack[self.top] = item
Driver code:

Push(3) top = 2
stack.push(3)

Code running
behind the scene:
3

def push(self, item):


if self.top == len(self.stack) - 1:
2
print("Stack overflow")
else:
self.top += 1
1 self.stack[self.top] = item
Driver code:

Push(4) top = 3
stack.push(4)
4

Code running
behind the scene:
3

def push(self, item):


if self.top == len(self.stack) - 1:
2
print("Stack overflow")
else:
self.top += 1
1 self.stack[self.top] = item
Driver code:

Push(5) top = 3
stack.push(5)
4
Stack Overflow Error!
Code running
behind the scene:
3

def push(self, item):


if self.top == len(self.stack) - 1:
2
print("Stack overflow")
else:
self.top += 1
1 self.stack[self.top] = item
Peek top = 3 Driver code:

4 print(stack.peek())

4 3 Code running
behind the scene:

def peek(self):
Will return 4, but
2 if self.top == -1:

will not remove 4 print("Stack is empty ")

from the stack else:


1 return
self.stack[self.top]
Pop top = 2 Driver code:

print(stack.pop())

4 3 Code running
behind the scene:

def pop(self):

Will return 4 and


2 if self.top == -1:
print("Stack underflow")
remove 4 from else:
the stack item = self.stack[self.top]
1 self.stack[self.top] = None
self.top -= 1
return item
Pop top = 1 Driver code:

stack.pop()

Code running
behind the scene:

def pop(self):

Will remove 3
2 if self.top == -1:
print("Stack underflow")
from the stack else:
item = self.stack[self.top]
1 self.stack[self.top] = None
self.top -= 1
return item
Pop top = 0 Driver code:

stack.pop()

Code running
behind the scene:

def pop(self):

Will remove 2 if self.top == -1:


print("Stack underflow")
from the stack else:
item = self.stack[self.top]
1 self.stack[self.top] = None
self.top -= 1
return item
Pop top = -1 Driver code:

stack.pop()

Code running
behind the scene:

def pop(self):

Will remove 1 if self.top == -1:


print("Stack underflow")
from the stack else:
item = self.stack[self.top]
self.stack[self.top] = None
self.top -= 1
return item
Pop top = -1 Driver code:

stack.pop()

Stack Underflow
Error! Code running
behind the scene:

def pop(self):
if self.top == -1:
print("Stack underflow")
else:
item = self.stack[self.top]
self.stack[self.top] = None
self.top -= 1
return item
Linked List Based Implementation
Stack Creation
Push
Pop
Peek
Stack Applications
1. Call Stacks

def main:
A()

def A:
B()

def B:
print("hello world")

main()
Stack Applications Hello

2. Reverse a word
def reverse_word(word):
word = "Hello"
stack = Stack()
reversed_word = reverse_word(word)
print(reversed_word)
# Push each character of the word onto the stack
for char in word:
stack.push(char)

reversed_word = ""

# Pop each character from the stack to get the reversed word olleH
while not stack.is_empty():
reversed_word += stack.pop()

return reversed_word
Stack Applications

3. Undo

4. Browser back button


Stack Applications

5. Postfix Expression Evaluation

6. Parenthesis Matching
Postfix Expression Evaluation

● To understand this problem, first we


need to know, what is an expression
tree? And what is postfix expression?
Expression Tree

● This is an expression:
Expression Tree
Prefix Traversal pre

root , left, right


Prefix Traversal pre

root , left, right

x
Prefix Traversal pre

root , left, right

x +52
Prefix Traversal pre

root , left, right

x +52 -31
Prefix Traversal pre

root , left, right

x +52 -31

Ans: x + 5 2 - 3 1
Infix Traversal in

left, root, right


Infix Traversal in

left, root, right


Infix Traversal in

left, root, right

5+2
Infix Traversal in

left, root, right

5+2 x
Infix Traversal in

left, root, right

5+2 x 3-1

Same as this:
Postfix Traversal post

left, right, root


Postfix Traversal post

left, right, root

52+ 31- x

Ans:
Postfix Expression Evaluation

● Back to stack applications.


Given a postfix expression, like above, a
stack helps us evaluate (calculate and find
the value) of that expression.
Postfix Expression Evaluation
Input:

# your code

Output: 14

Explanation: (5+2) x (3-1) = 14, right?


Postfix Expression Evaluation
Possible solution:

Take characters one by one from the beginning

If character is an operand ( 5 / 2 / 3 )
Push to stack
If character is an operator ( + * / - )
Pop last two characters from stack
Perform operation on last two characters
Push answer to stack
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
5 2 + 3 1- x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
Perform operation on last two
characters
Push answer to stack
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
52+31-x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
Perform operation on last two
characters
Push answer to stack

5
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
52+31-x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
Perform operation on last two
characters
Push answer to stack
2

5
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
52+31-x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
Perform operation on last two
characters
Push answer to stack

5 + 2 = 7
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
52+31-x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
Perform operation on last two
characters
Push answer to stack

7 5 + 2 = 7
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
52+31-x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
Perform operation on last two
characters
Push answer to stack
3
7
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
52+31-x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
1 Perform operation on last two
characters
Push answer to stack
3
7
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
52+31-x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
Perform operation on last two
characters
Push answer to stack
2
7 3 - 1 = 2
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
52+31-x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
Perform operation on last two
characters
Push answer to stack
2
7
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
52+31-x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
Perform operation on last two
characters
Push answer to stack

7 x 2 = 14
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
52+31-x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
Perform operation on last two
characters
Push answer to stack

14 7 x 2 = 14
Postfix Expression Evaluation
Possible solution:

Take characters one by one from the


beginning
52+31-x
If character is an operand
Push to stack
If character is an operator
Pop last two characters from stack
Perform operation on last two
characters
Push answer to stack

14
Postfix Expression Evaluation - Another Example
Parenthesis Matching
Input: exp = “[()]{}{[()()]()}”
Output: Balanced

Input: exp = “[(])”


Output: Not Balanced
Parenthesis Matching
Follow the steps mentioned below to implement the idea:
● Declare a character stack (say temp).
● Now traverse the string exp.
● If the current character is a starting bracket ( ‘(‘ or ‘{‘ or ‘[‘ ) then push it to stack.
● If the current character is a closing bracket ( ‘)’ or ‘}’ or ‘]’ ) then pop from the stack and if
the popped character is the matching starting bracket then fine.
● Else brackets are Not Balanced.
● After complete traversal, if some starting brackets are left in the stack then the expression is Not
balanced, else Balanced.
Parenthesis Matching
Parenthesis Matching
Parenthesis Matching
Stack Applications

5. Postfix Expression Evaluation

6. Parenthesis Matching

Try writing both programs yourselves.


Queue
Queue
Stack VS Queue
1

Stack ->
Queue-> First In First Out

Last In First Out


Push(1) stack
queue

Enqueue(1)
Push(2) stack
queue

1 2

Enqueue(2)
Push(3) stack
queue

1 2 3

Enqueue(3)
Push(4) stack
queue

4 1 2 3 4

Enqueue(4)
Peek stack
queue

4 1 2 3 4

4
3

Will return 4, 1
2
but will not
remove 4 from Will return 1,
the stack but will not
1
remove 1 from
the queue Peek
Pop stack
queue

4 2 3 4

3
1

Will return 4 and 2


remove 4 from the Will return 1 and remove 1
stack from the queue
1

Dequeue
Pop stack
queue

3 4

Dequeue
Pop stack
queue

2
3

Dequeue
Pop stack
queue

Dequeue
Queue
A queue has three main operations (like a stack). These operations are:
1. Enqueue: It stores a new object in the queue at the end. If the queue is full, this
operation throws a QueueOverflow exception.
2. Dequeue: It removes the first object from the queue. If the queue is empty, this
operation throws a QueueUnderflow exception.
3. Peek: This operation shows the first item in the queue. This operation does not
remove any items from the queue. If the queue is empty, this operation throws a
QueueUnderflow exception.
Queue def dequeue(self):
if self.size == 0:
class Queue:
print("Queue is empty")
def __init__(self, max_size):
return None
self.max_size = max_size
item = self.queue[self.front]
self.queue = [None] * max_size
self.queue[self.front] = None
self.front = 0
self.front = (self.front + 1) % self.max_size
self.rear = -1
self.size -= 1
self.size = 0
return item

def enqueue(self, item):


def peek(self):
if self.size == self.max_size:
if self.size == 0:
print("Queue is full")
print("Queue is empty")
return
return None
self.rear = (self.rear + 1) %
return self.queue[self.front]
self.max_size
self.queue[self.rear] = item
self.size += 1
Sidenote: A Refresher On Modular Operations
0%4 = 0

1%4 = 1

2%4 = 2

3%4 = 3

4%4 = 0

5%4 = 1

6%4 = 2
Queue() #when __init__ is called
size = 0 max_size=4
front=0

def __init__(self, max_size):

rear=-1 self.max_size = max_size


self.queue = [None] *
max_size
self.front = 0
self.rear = -1
self.size = 0
Enqueue(1)
size = 1 max_size=4
front=0

def enqueue(self, item):


rear=0 if self.size == self.max_size:
print("Queue is full")
return
self.rear = (self.rear + 1) %
self.max_size
self.queue[self.rear] = item
self.size += 1
Enqueue(2)
size = 2 max_size=4
front=0

1 2

def enqueue(self, item):


rear=1 if self.size == self.max_size:
print("Queue is full")
return
self.rear = (self.rear + 1) %
self.max_size
self.queue[self.rear] = item
self.size += 1
Enqueue(3)
size = 3 max_size=4
front=0

1 2 3

def enqueue(self, item):


rear=2 if self.size == self.max_size:
print("Queue is full")
return
self.rear = (self.rear + 1) %
self.max_size
self.queue[self.rear] = item
self.size += 1
Enqueue(4)
size = 4 max_size=4
front=0

1 2 3 4

def enqueue(self, item):


rear=3 if self.size == self.max_size:
print("Queue is full")
return
self.rear = (self.rear + 1) %
self.max_size
self.queue[self.rear] = item
self.size += 1
Enqueue(5) Queue Overflow Error!

size = 4 max_size=4
front=0

1 2 3 4

def enqueue(self, item):


rear=3 if self.size == self.max_size:
print("Queue is full")
return
self.rear = (self.rear + 1) %
self.max_size
self.queue[self.rear] = item
self.size += 1
Peek
size = 4 max_size=4
front=0

1 2 3 4

def peek(self):
rear=3 if self.size == 0:
print("Queue is empty")
return None
Will return 1 but will not
return self.queue[self.front]
1 remove it
Dequeue
size = 3 max_size=4
front=1
def dequeue(self):
if self.size == 0:
2 3 4
print("Queue is empty")
return None
item = self.queue[self.front]
rear=3 self.queue[self.front] = None
self.front = (self.front + 1) %
self.max_size
Will return 1 and remove it self.size -= 1
1 return item
Dequeue
size = 2 max_size=4
front=2
def dequeue(self):
if self.size == 0:
3 4
print("Queue is empty")
return None
item = self.queue[self.front]
rear=3 self.queue[self.front] = None
self.front = (self.front + 1) %
self.max_size
self.size -= 1
2 return item
Dequeue
size = 1 max_size=4
front=3
def dequeue(self):
if self.size == 0:
4
print("Queue is empty")
return None
item = self.queue[self.front]
rear=3 self.queue[self.front] = None
self.front = (self.front + 1) %
self.max_size
self.size -= 1
3 return item
What will happen if I dequeue now?

Dequeue Think!

size = 1 max_size=4
front=3
def dequeue(self):
if self.size == 0:
4
print("Queue is empty")
return None
item = self.queue[self.front]
rear=3 self.queue[self.front] = None
self.front = (self.front + 1) %
self.max_size
self.size -= 1
3 return item
front % max_size = 4%4 = 0

Dequeue
size = 0 max_size=4
front=0
def dequeue(self):
if self.size == 0:
print("Queue is empty")
return None
item = self.queue[self.front]
rear=3 self.queue[self.front] = None
self.front = (self.front + 1) %
self.max_size
self.size -= 1
4 return item
Dequeue Queue Underflow Error!

size = 0 max_size=4
front=0
def dequeue(self):
if self.size == 0:
print("Queue is empty")
return None
item = self.queue[self.front]
rear=3 self.queue[self.front] = None
self.front = (self.front + 1) %
self.max_size
self.size -= 1
return item
size = 0 max_size=4
front=0

rear=3

What will happen if I enqueue


something now? Think!
rear % max_size = 4%4 = 0

Enqueue(1)
size = 1 max_size=4
front=0

def enqueue(self, item):


rear=0 if self.size == self.max_size:
print("Queue is full")
return
self.rear = (self.rear + 1) %
self.max_size
self.queue[self.rear] = item
self.size += 1
Queue - Linked List Based Implementation
Not fixed sized, no need for
modular operations
Simulations
Type 1

You need to do the following operations on a queue:

enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue.


enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

enq(a)
a
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

enq(a) enq(b)
a ab
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

enq(a) enq(b)
a ab

()
deq

b
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

enq(a) enq(b)
a ab

()
deq

(b)
peek()
b b
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

enq(a) enq(b)
a ab

()
deq

(b)
peek() enq(c)
b b bc
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

enq(a) enq(b)
a ab

()
deq

(b)
peek() enq(c)
b b bc

peek()
(c)

bc
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

enq(a) enq(b)
a ab

()
deq

(b)
peek() enq(c)
b b bc

peek()
(c)

deq()
bc c
In exam, write your answer like this
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue
Simulations
Type 2

You need to perform the following operations on a array based queue where
the length of array is 4 and starting index of front and back is 3.
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue.
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

0 1 2 3 front rear
N N N N 3 3
enq(a)

enq(b)

deq()

peek()

enq(c)

peek()

deq()

(N=None)
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

0 1 2 3 front rear
N N N N 3 3
enq(a) N N N a 0
enq(b)

deq()

peek()

enq(c)

peek()

deq()

(N=None)
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

0 1 2 3 front rear
N N N N 3 3
enq(a) N N N a 0
enq(b) b N N a 1
deq()

peek()

enq(c)

peek()

deq()

(N=None)
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

0 1 2 3 front rear
N N N N 3 3
enq(a) N N N a 0 0
enq(b) b N N a 1
deq() b N N N

peek()

enq(c)

peek()

deq()

(N=None)
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

0 1 2 3 front rear
N N N N 3 3
enq(a) N N N a 0 0
enq(b) b N N a 1
deq() b N N N

peek() b N N N

enq(c)

peek()

deq()

(N=None)
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

0 1 2 3 front rear
N N N N 3 3
enq(a) N N N a 0 0
enq(b) b N N a 1
deq() b N N N 2
peek() b N N N

enq(c) b c N N

peek()

deq()

(N=None)
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

0 1 2 3 front rear
N N N N 3 3
enq(a) N N N a 0 0
enq(b) b N N a 1
deq() b N N N 2
peek() b N N N

enq(c) b c N N

peek() b c N N

deq()

(N=None)
enqueue a, enqueue b, dequeue, peek, enqueue c, peek, dequeue

0 1 2 3 front rear
N N N N 3 3
enq(a) N N N a 0 0
enq(b) b N N a 1 1
deq() b N N N 2
peek() b N N N

enq(c) b c N N

peek() b c N N

deq() N c N N

(N=None)
In exam, write your answer like this
A Discussion on the Importance of Stacks and Queues
By now you well understand that larger complex data structures are made of
smaller building block data structures. For example, multi-dimensional and
circular arrays or vectors are made using linear arrays; lists are used to create
sets and maps (which is called a dictionary in some languages and associated
arrays in some other). However, as building block data structures, stacks and
queues are unique in some sense.
A Discussion on the Importance of Stacks and Queues
For example, a set or a map that you create from a linked list provides
additional features over their building block component that is the list.
However, stacks and queues are strictly restricted forms of linked list (in rare
cases, where you know the maximum number of elements you will put in
them, you can use arrays for stacks and queues also). In other words, they do
not provide any new features that a linked list does not already have. So it is a
natural question why stacks and queues are considered fundamental data
structures.
A Discussion on the Importance of Stacks and Queues
One reason for their importance is that scenarios where you need a linked list
behave like a stack or queue is very frequent. For example, you need stacks
for language parsing, expression evaluation, function calls, efficient graph
traversals, etc. Queues are similarly important for resource scheduling, time
sharing of CPU among candidate processes, message routing in network
switches and routers, and efficient graph traversal.
A Discussion on the Importance of Stacks and Queues
Another central reason is that you often do not want to give access to the underlying list data
structure that forms a stack or queue to the code that requested an insert or a removal from the
stack/queue. If access to the list is provided then the code becomes more insecure. To consider this
case, imagine direct access to the function call stack is possible. Then a program can manipulates the
stack and jump from the current function to a much earlier function, instead of the immediate
predecessor function that called it. Why this might be a problem? Well, this would not be a problem if
all the functions in the stack belong to your own program. However, in real-world, library functions,
operating system’s service functions interleave with user program’s functions in the stack.
Unprotected jumps to those functions can crash the system.
A Discussion on the Importance of Stacks and Queues
A third reason to have stack and queues as restricted form of linked lists (or
arrays) is that their restricted functions provide smaller code that can fit in
very short memory or can even be implemented inside hardware devices
directly. This feature is particularly important when you need fast response,
for example, in routers and switches. In fact, array based stack and queue
implementations are most suited in cases like this.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy