0% found this document useful (0 votes)
4 views

Stack DS Python

The document provides an overview of the stack data structure in Python, detailing its characteristics, operations, and various implementation methods including lists, collections.deque, and linked lists. It also covers practical applications such as function calls, expression evaluation, and sorting elements. Additionally, it includes code examples for implementing stacks and related algorithms like reversing a stack and checking for balanced parentheses.

Uploaded by

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

Stack DS Python

The document provides an overview of the stack data structure in Python, detailing its characteristics, operations, and various implementation methods including lists, collections.deque, and linked lists. It also covers practical applications such as function calls, expression evaluation, and sorting elements. Additionally, it includes code examples for implementing stacks and related algorithms like reversing a stack and checking for balanced parentheses.

Uploaded by

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

stack data structure in python

------------------------------

introduction:
~~~~~~~~~~~~~
=> a stack is linear data structure.
=> memory allocation for objects are continueos memory locations.
=> last - in - first - out LIFO

Eg:
---
stack of plates
disks in the rack
function calls are stored inside stack
web page navigations
parenthesis balancing
reversing item
infix to prefix/postfix
evaluation of prefix/postfix
undo/redo or forward/backward
etc

operations that can be performed on stack


-----------------------------------------
The following are some of operations that can be performed on stack

1) push ---> inserting an object into stack


2) pop ----> deleteing an object from stack
3) peek ---> returning top most object in the stack
4) size ---> returns num of objects in the stack
5) isempty-> returns True if the stack is empty else False
6) display-> display/traverse elements in the stack

implementation of stack
-----------------------
container and top

when an obj is inserted top will be incremented by one unit


when an obj is deleted top will be decremented by one unit

1) using list
2) collections. deque
3) using our own implementation

stack implementation by using list


----------------------------------
L = []
print(L) #[]
L.append(111)
L.append(222)
L.append(333)
L.append(444)
L.append(555)
print(L) #[111, 222, 333, 444, 555]
print(L[-1]) #555
print(L) #[111, 222, 333, 444, 555]
L.pop()
print(L) #[111, 222, 333, 444]
print(len(L)==0)
print(len(L))

C:\test>py test.py
[]
[111, 222, 333, 444, 555]
555
[111, 222, 333, 444, 555]
[111, 222, 333, 444]
False
4

stack implementation by using collections.deque


------------------------------------------------
from collections import deque

stack = deque()

stack.append(10)
stack.append(20)
stack.append(30)
stack.append(40)

print(stack) #[10,20,30,40]
print(stack[-1]) #40
stack.pop()
print(stack)

C:\test>py test.py
deque([10, 20, 30, 40])
40
deque([10, 20, 30])

stack implementation by our own list


------------------------------------
class stack:

#constructor for initializations


def __init__(self):
self.stk = []

#isempty operation
def isempty(self):
return len(self.stk)==0

#size of stack
def size(self):
return len(self.stk)

#print or display or traversing


def display(self):
print(self.stk)

#push operation
def push(self,data):
self.stk.append(data)

#pop operation
def pop(self):
if self.isempty():
print("stack is underflow")
return
return self.stk.pop()

s = stack()
s.push(111)
s.push(222)
s.display()
print(s.pop())
s.display()

C:\test>py test.py
[111, 222]
222
[111]

stack implementation by using linked list


-----------------------------------------
class stack:

class node:

def __init__(self,data,next=None):
self.data = data
self.next = next

#constructor for initializations


def __init__(self):
self.head = None
self.count = 0

#isempty operation
def isempty(self):
return self.count==0

#peek operation
def peek(self):
if self.isempty():
print("stack is empty")
return
return self.head.data

#size of stack
def size(self):
return self.count

#print or display or traversing: O(n)


def display(self):
if self.isempty():
print("list is empty")
return
temp = self.head
while temp!=None:
print(temp.data,end=" ")
temp = temp.next
print()
#push operation
def push(self,data):
self.head = self.node(data,self.head)
self.count = self.count + 1

#pop operation
def pop(self):
if self.isempty():
print("stack is underflow")
return
val = self.head.data
self.count = self.count -1
self.head = self.head.next
return val

s = stack()
s.push(100)
s.push(200)
s.push(300)
s.display()
print(s.pop())
s.display()
print(s.peek())
print(s.size())

C:\test>py test.py
300 200 100
300
200 100
200
2

system stack and function calls


-------------------------------
def fun2():
print("function2 line num 1")

def fun1():
print("function1 line num 1")
fun2()
print("function1 line num 2")

def main():
print("main line num 1")
fun1()
print("main line num 2")

main()
'''
main line num1
function1 line num 1
function2 line num 1
function1 line num 2
main line num 2
'''

stack.py
--------
class stack:

class node:

def __init__(self,data,next=None):
self.data = data
self.next = next

#constructor for initializations


def __init__(self):
self.head = None
self.count = 0

#isempty operation
def isempty(self):
return self.count==0

#peek operation
def peek(self):
if self.isempty():
print("stack is empty")
return
return self.head.data

#size of stack
def size(self):
return self.count

#print or display or traversing: O(n)


def display(self):
if self.isempty():
print("list is empty")
return
temp = self.head
while temp!=None:
print(temp.data,end=" ")
temp = temp.next
print()

#push operation
def push(self,data):
self.head = self.node(data,self.head)
self.count = self.count + 1

#pop operation
def pop(self):
if self.isempty():
print("stack is underflow")
return
val = self.head.data
self.count = self.count -1
self.head = self.head.next
return val

stack to maintain student objects


---------------------------------
from stack import *
class student:
def __init__(self,sid,sname):
self.sid = sid
self.sname = sname
def __str__(self):
return f"({self.sid}, {self.sname})"

s1 = student(111,"AAA")
s2 = student(222,"BBB")
s3 = student(333,"CCC")
s4 = student(444,"DDD")
s = stack()
s.push(s1)
s.push(s2)
s.push(s3)
s.push(s4)
s.display()
print(s.pop())
s.display()

C:\test>py test.py
(444, DDD) (333, CCC) (222, BBB) (111, AAA)
(444, DDD)
(333, CCC) (222, BBB) (111, AAA)

sorted insertion into stack


---------------------------
from stack import *

def sortedinsert(s,data):
if s.isempty() or data>s.peek():
s.push(data)
else:
temp = s.pop()
sortedinsert(s,data)
s.push(temp)

s = stack()
sortedinsert(s,4)
sortedinsert(s,5)
sortedinsert(s,1)
sortedinsert(s,2)
sortedinsert(s,3)
sortedinsert(s,6)
s.display()

sorting stack elements


----------------------
from stack import *

def sortedinsert(s,data):
if s.isempty() or data>s.peek():
s.push(data)
else:
temp = s.pop()
sortedinsert(s,data)
s.push(temp)

def sortstack(s):
if not s.isempty():
temp = s.pop()
sortstack(s)
sortedinsert(s,temp)

s = stack()
s.push(444)
s.push(111)
s.push(222)
s.push(333)
s.push(666)
s.push(555)
s.display()
sortstack(s)
s.display()

bottom insert in the stack


--------------------------
from stack import *

def bottominsert(s,data):
if s.isempty():
s.push(data)
else:
temp = s.pop()
bottominsert(s,data)
s.push(temp)

s = stack()
s.push(444)
s.push(111)
s.push(222)
s.push(333)
s.display()
bottominsert(s,999)
s.display()

C:\test>py test.py
333
222
111
444

333
222
111
444
999

reverse stack
~~~~~~~~~~~~~
from stack import *

def reversestack(s):
if not s.isempty():
temp = s.pop()
reversestack(s)
bottominsert(s,temp)

def bottominsert(s,data):
if s.isempty():
s.push(data)
else:
temp = s.pop()
bottominsert(s,data)
s.push(temp)

s = stack()
s.push(444)
s.push(111)
s.push(222)
s.push(333)
s.display()
reversestack(s)
s.display()

C:\test>py test.py
333 222 111 444
444 111 222 333

reverse a stack by using queue


------------------------------
stack ----> LIFO
queue ----> FIFO

from queue import *


from stack import *

def reversestack(s):
q = Queue(maxsize=5)
while not s.isempty():
q.put(s.pop())
while not q.empty():
s.push(q.get())

s = stack()
s.push(111)
s.push(222)
s.push(333)
s.push(444)
s.push(555)
s.display()
reversestack(s)
s.display()

C:\test>py test.py
555 444 333 222 111
111 222 333 444 555

reverse k elements in stack


---------------------------
from queue import *
from stack import *

def reversestack(s,k):
q = Queue(maxsize=5)
i=1
while not s.isempty() and i<=k:
q.put(s.pop())
i=i+1
while not q.empty():
s.push(q.get())

s = stack()
s.push(111)
s.push(222)
s.push(333)
s.push(444)
s.push(555)
s.push(666)
s.push(777)
s.display()
reversestack(s,3)
s.display()

C:\test>py test.py
777 666 555 444 333 222 111
555 666 777 444 333 222 111

balanced parenthesis
~~~~~~~~~~~~~~~~~~~~
() True
{} True
[] True
([]) True
()[] True
([{]}) False

def balanced_parenthesis(expr):
s = []
for ch in expr:
if ch=='(' or ch=='[' or ch=='{':
s.append(ch)
elif ch==')':
if s.pop() != '(':
return False
elif ch==']':
if s.pop()!='[':
return False
elif ch=='}':
if s.pop()!='{':
return False
return len(s)==0

print(balanced_parenthesis("()")) #True
print(balanced_parenthesis("([])")) #True
print(balanced_parenthesis("([{}])")) #True
print(balanced_parenthesis("([{]})")) #False

C:\test>py test.py
True
True
True
False
Representation of expressions in programming
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
infix ----> operand operator operand
prefix ---> operator operand operand
postfix --> operand operand operator

infix prefix postfix


---------------------------------------
A+B +AB AB+
A+(B*C) +A*BC ABC*+
(A+B)*C *+ABC AB+C*
A*B+C*D +*AB*CD AB*CD*+

steps to convert infix expr into postfix form


---------------------------------------------
1) print operands in the same order they arrive.
2) if stack is empty or contains ( on top, then push incoming operator
3) if incoming symbol is ( then push into stack.
4) if incoming symbol is ) pop all items into output until ( came.
5) if the precedence of incoming symbol is >= precedence of symbol existed in the
top of stack, push that symbol into stack.
6) if the precedence of incoming symbol is < precedence of symbol existed in the
top of stack,pop the symbol from stack put it into output, then compare next symbol
else push that symbol into stack.
7) pop all symbols from stack put into output.

infix to postfix conversion implementation


------------------------------------------
def precedence(x):
if x=='(':
return 0
if x=='+' or x=='-':
return 1
if x=='*' or x=='/':
return 2
return 4

def infix_to_postfix_conversion(expn):
s = []
tokens=list(expn)
result = ""
for item in tokens:
if item in "+-*/":
while len(s)!=0 and precedence(item) <= precedence(s[-1]):
result=result+s.pop()
s.append(item)
elif item=='(':
s.append(item)
elif item==')':
temp=None
while len(s)!=0 and temp!='(':
temp = s.pop()
if temp!='(':
result = result + temp
else:
result=result+item
while len(s)!=0:
result = result + s.pop()
return result

print(infix_to_postfix_conversion("A+B")) #A
print(infix_to_postfix_conversion("A+(B*C)"))
print(infix_to_postfix_conversion("(A+B)*C)"))
print(infix_to_postfix_conversion("A*B+C*D"))

C:\test>py test.py
AB+
ABC*+
AB+C*
AB*CD*+

steps to convert infix expr into prefix form


--------------------------------------------
1) reverse the given expression
2) replace '(' with ')' and '(' with ')'
3) apply infix to postfix conversion
4) reverse generated output

infix to prefix conversion implementation


------------------------------------------
def precedence(x):
if x=='(' or x==')':
return 0
if x=='+' or x=='-':
return 1
if x=='*' or x=='/':
return 2
return 4

def infix_to_postfix_conversion(expn):
s = []
tokens=list(expn)
result = ""
for item in tokens:
if item in "+-*/":
while len(s)!=0 and precedence(item) <= precedence(s[-1]):
result=result+s.pop()
s.append(item)
elif item=='(':
s.append(item)
elif item==')':
temp=None
while len(s)!=0 and temp!='(':
temp = s.pop()
if temp!='(':
result = result + temp
else:
result=result+item
while len(s)!=0:
result = result + s.pop()
return result

def replace(expn):
s = ""
for i in expn:
if i=='(':
s=s+')'
elif i==')':
s=s+'('
else:
s=s+i
#print(s)
return s

def infix_to_prefix_conversion(expn):
expn = expn[::-1]
expn = replace(expn)
expn = infix_to_postfix_conversion(expn)
expn = expn[::-1]
return expn

print(infix_to_postfix_conversion("A+(B*C)")) #ABC*+
print(infix_to_prefix_conversion("A+(B*C)")) #+A*BC
print(infix_to_postfix_conversion("A+B")) #AB+
print(infix_to_prefix_conversion("A+B")) #+AB
print(infix_to_postfix_conversion("(A+B)*C)")) #AB+C*
print(infix_to_prefix_conversion("(A+B)*C"))#*+ABC
print(infix_to_postfix_conversion("A*B+C*D"))
print(infix_to_prefix_conversion("A*B+C*D"))

C:\test>py test.py
ABC*+
+A*BC
AB+
+AB
AB+C*
*+ABC
AB*CD*+
+*AB*CD

eval of prefix
eval of postfix

queue

8PM to 10PM

You might also like