Dsapb3 Notes
Dsapb3 Notes
course:
-------
title -----> data structures and algorithms with python (DSAPB3)
timings ---> 11am to 12.15pm (monday to saturday)
duration --> 2 months (july and aug)
fees ------> Rs.999/-
contact ---> 9246 212143 or 7207 212427 or
[email protected]
content ---> Running Notes (GDrive) + Videos (GDrive) [6 months access]
https://www.youtube.com/watch?v=TUBPM_-yCNE&list=PLd3UqWTnYXOm5NBgfgE-
K2r8WxgTaJeUX
syllabus:
---------
01. introduction to data structures and algorithms
02. analysis of algorithms or complexities of algorithms
03. sample problems with python implementations [25 programs]
04. python inbuilt data structures (str, list, tuple, set & dict)
05. str data structure
06. programs on str data structure
07. list/array data structure
08. list/array based programs
09. recursion
10. recursion based applications
11. sorting algorithms
12. searching algorithms
13. divide and conquer algorithms
14. backtracking (N-Queens, Sudoku)
15. dynamic programming
16. greedy algorithms
17. linked list data strcture
18. stack data strcture
19. queue data strcture
20. hashtable/hashing data strcture
21. tree data strctures
22. priority queues / heaps
23. graph data strctures
24. bit manipulations
def fun2(n):
#recursion
if n==0:
return 1
return n*fun2(n-1)
def fun3(n):
return math.factorial(n)
for i in range(6):
print(f"{i}\t{fun1(i)}\t{fun2(i)}\t{fun3(i)}")
C:\test>py test.py
0 1 1 1
1 1 1 1
2 2 2 2
3 6 6 6
4 24 24 24
5 120 120 120
Linked List:
------------
collection of nodes is called as linked list, where every node is linked
with another node.
def display():
if head==None:
print("list is empty")
return
currNode = head
while currNode!=None:
print(currNode.data)
currNode = currNode.next
def insertatfirst(data):
newnode = node(data)
if head==None:
head = newnode
return
newnode.next = head
head = newnode
def insertatlast(data):
newnode = node(data)
if head==None:
head = newnode
return
currNode = head
while currNode.next!=None:
currNode = currNode.next
currNode.next = newnode
def prime1(n):
f=0
for i in range(1,n+1):
if n%i==0:
f=f+1
return f==2
def prime2(n):
for i in range(2,n):
if n%i==0:
return False
return True
def prime3(n,i):
if i==1:
return True
if n%i==0:
return False
return prime3(n,i-1)
for i in range(2,11):
print(f"{i} \t {prime1(i)} \t {prime2(i)} \t {prime3(i,i//2)}")
C:\test>py test.py
2 True True True
3 True True True
4 False False False
5 True True True
6 False False False
7 True True True
8 False False False
9 False False False
10 False False False
algorithm:
----------
step by step process for solving any problem.
flowchart:
----------
pictorial or diagrametic representation of an algorithm is called as
flowchart
implementation:
---------------
a = int(input("Enter first number: "))
b = int(input("Enter second number: "))
c = a + b
print(f"a:{a}, b:{b} and addition:{c}")
C:\test>py test.py
Enter first number: 10
Enter second number: 20
a:10, b:20 and addition:30
advantages of algorithms:
-------------------------
==> problem will be simplified.
==> easy to understand the problem statement.
==> easy to implement by using any programming language.
==> we will get a format / template / pattern for solving the problem.
properties of an algorithm:
---------------------------
1) every algorithm should take zero or more inputs.
2) every algorithm should print atleast one output.
3) deterministic (input --> output same thing should happend if u run
again)
4) instructions are very clear and unambigious
5) terminate at finate number of steps
6) efficient (logic should be clear)
types of algorithms:
--------------------
1) simple algorithms
2) math algorithms (formulas)
3) recursive algorithms
4) divide and conquer algorithms
5) back tracking algorithms
6) dynamic programming
7) greedy algorithms
8) searching and sorting methods
etc
data structure:
---------------
data structure is the concept of organzing data. data structures are
classified into two types.
Ex:
arrays/list
strings
linked lists
stack
queue
pq
hashtable etc
Ex:
trees
graphs
heap
etc
The following are the basic operations, that can be performed on any ds
1) inserting
2) selecting
3) deleting
4) updating
5) searching etc
array / list
~~~~~~~~~~~~~
It is a collection / group of objects.
creation
insertion
delete
select/display
update
search
string
~~~~~~
It is a collection / group of characters. (ASCII/UNICODE)
create
insert
display/select
update
search
delete
linked list
~~~~~~~~~~~
It is also collection of objects, but those objects containes some extra
pointers (single node, double node).
insert
delete
display
update
search etc
insert
delete
update
display
search etc
insert
deletion
search
applications etc
insert
delete
search
applications etc
1) constraints (conditions)
2) idea generation
3) complexity analysis
4) coding
5) testing
1) constraints (conditions)
---------------------------
Given problem constraints are very very imp for solving any problem.
first we have to identify all the constraints related to the given
problem.
Ex:
sorting the data in order
2) idea generation
------------------
* more if you practice, you will get an idea.
* by practicing you will get a pattern or template of the program.
* easily we can solve unseen problem.
3) complexity analysis
----------------------
=> finding the solution for a proble is not good.
=> finding the solution which executes very fastly and takes less memory.
=> calculate time and space complexities of alg and go for impl.
4) coding
----------
=> if you have all the data, then we can write code.
=> select any programming langauge. (python)
=> select proper IDE
=> and try to write modular code (functions/methods) (reusability)
5) testing
----------
=> after completion of program, we have to supply some data and check
whether
the code is working or not.
=> pply varies main test cases and also corner test cases.
Ex:
A = [1, 2, 3, 4, 5]
0 ---> 1
100 -> ?
def fun1(n):
if n%2==0:
return True
else:
return False
def fun2(n):
return n%2==0
def fun3(n):
return (n&1)==0
C:\test>py test.py
Enter any number: 5
False
False
False
C:\test>py test.py
Enter any number: 6
True
True
True
def fun1(n1,n2):
if n1>n2:
return n1
else:
return n2
def fun2(n1,n2):
return n1 if n1>n2 else n2
def fun3(n1,n2):
return max(n1,n2)
C:\test>py test.py
Enter any number: 1
Enter any number: 2
2
2
2
C:\test>py test.py
Enter any number: 1
Enter any number: -2
1
1
1
def fun1(n1,n2,n3):
if n1>n2 and n1>n3:
return n1
elif n2>n3:
return n2
else:
return n3
def fun2(n1,n2,n3):
return n1 if n1>n2 and n1>n3 else n2 if n2>n3 else n3
def fun3(n1,n2,n3):
return max(n1,n2,n3)
print(fun1(n1,n2,n3))
print(fun2(n1,n2,n3))
print(fun3(n1,n2,n3))
C:\test>py test.py
Enter any number: 1
Enter any number: 2
Enter any number: 3
3
3
3
C:\test>py test.py
Enter any number: 1
Enter any number: 2
Enter any number: -3
2
2
2
C:\test>py test.py
Enter any number: 1
Enter any number: -2
Enter any number: -3
1
1
1
def fun1(n1,n2,n3,n4):
if n1>n2 and n1>n3 and n1>n4:
return n1
elif n2>n3 and n2>n4:
return n2
elif n3>n4:
return n3
else:
return n4
def fun2(n1,n2,n3,n4):
return n1 if n1>n2 and n1>n3 and n1>n4 else n2 if n2>n3 and n2>n4
else n3 if n3>n4 else n4
def fun3(n1,n2,n3,n4):
return max(n1,n2,n3,n4)
print(fun1(n1,n2,n3,n4))
print(fun2(n1,n2,n3,n4))
print(fun3(n1,n2,n3,n4))
C:\test>py test.py
Enter any number: 1
Enter any number: 2
Enter any number: 3
Enter any number: 4
4
4
4
C:\test>py test.py
Enter any number: 1
Enter any number: 2
Enter any number: 3
Enter any number: -4
3
3
3
C:\test>py test.py
Enter any number: 1
Enter any number: 2
Enter any number: -3
Enter any number: -4
2
2
2
C:\test>py test.py
Enter any number: 1
Enter any number: -2
Enter any number: -3
Enter any number: -4
1
1
1
def swap_version2(a,b):
print(f"Before swaping => a: {a} and b: {b}")
a,b = b,a
print(f"After swaping => a: {a} and b: {b}")
def swap_version3(a,b):
print(f"Before swaping => a: {a} and b: {b}")
a = a + b
b = a - b
a = a - b
print(f"After swaping => a: {a} and b: {b}")
def swap_version4(a,b):
print(f"Before swaping => a: {a} and b: {b}")
a = a * b
b = a // b
a = a // b
print(f"After swaping => a: {a} and b: {b}")
def swap_version5(a,b):
print(f"Before swaping => a: {a} and b: {b}")
a = a ^ b
b = a ^ b
a = a ^ b
print(f"After swaping => a: {a} and b: {b}")
swap_version1(a,b)
swap_version2(a,b)
swap_version3(a,b)
swap_version4(a,b)
swap_version5(a,b)
C:\test>py test.py
Enter first number: 1
Enter second number: 2
Before swaping => a: 1 and b: 2
After swaping => a: 2 and b: 1
Before swaping => a: 1 and b: 2
After swaping => a: 2 and b: 1
Before swaping => a: 1 and b: 2
After swaping => a: 2 and b: 1
Before swaping => a: 1 and b: 2
After swaping => a: 2 and b: 1
Before swaping => a: 1 and b: 2
After swaping => a: 2 and b: 1
def fun2(n):
return n if n>0 else -n
def fun3(n):
return abs(n)
C:\test>py test.py
Enter n value: 10
num: 10 and abs value: 10
num: 10 and abs value: 10
num: 10 and abs value: 10
C:\test>py test.py
Enter n value: -10
num: -10 and abs value: 10
num: -10 and abs value: 10
num: -10 and abs value: 10
def fun2(n):
return (n*(n+1))//2
def fun3(n):
if n==0:
return 0
return n+fun3(n-1)
C:\test>py test.py
Enter n value: 5
num: 5 and sum of 5 natural nums: 15
num: 5 and sum of 5 natural nums: 15
num: 5 and sum of 5 natural nums: 15
C:\test>py test.py
Enter n value: 0
num: 0 and sum of 0 natural nums: 0
num: 0 and sum of 0 natural nums: 0
num: 0 and sum of 0 natural nums: 0
C:\test>py test.py
Enter n value: 10
num: 10 and sum of 10 natural nums: 55
num: 10 and sum of 10 natural nums: 55
num: 10 and sum of 10 natural nums: 55
def fun1(n):
f=1
for i in range(1,n+1):
f=f*i
return f
def fun2(n):
if n==0:
return 1
return n*fun2(n-1)
def fun3(n):
return math.factorial(n)
n = int(input("Enter n value: "))
print(f"num: {n} and factorial: {fun1(n)}")
print(f"num: {n} and factorial: {fun2(n)}")
print(f"num: {n} and factorial: {fun3(n)}")
C:\test>py test.py
Enter n value: 5
num: 5 and factorial: 120
num: 5 and factorial: 120
num: 5 and factorial: 120
C:\test>py test.py
Enter n value: 0
num: 0 and factorial: 1
num: 0 and factorial: 1
num: 0 and factorial: 1
C:\test>py test.py
Enter n value: 3
num: 3 and factorial: 6
num: 3 and factorial: 6
num: 3 and factorial: 6
while n!=0:
d = n % 10
print(d)
n = n // 10
C:\test>py test.py
Enter n value: 123
3
2
1
C:\test>py test.py
Enter n value: 1278
8
7
2
1
C:\test>py test.py
Enter n value: 121
1
2
1
10. count number of digits in the given number
----------------------------------------------
n = int(input("Enter n value: "))
count = 0
while n!=0:
count=count+1
n = n // 10
C:\test>py test.py
Enter n value: 1234
Number of digits: 4
C:\test>py test.py
Enter n value: 555
Number of digits: 3
print(f"Reverse: {rev}")
C:\test>py test.py
Enter n value: 1234
Reverse: 4321
C:\test>py test.py
Enter n value: 789
Reverse: 987
C:\test>py test.py
Enter n value: 999
Reverse: 999
C:\test>py test.py
Enter n value: 123
No
C:\test>py test.py
Enter n value: 121
Yes
C:\test>py test.py
Enter n value: 789
No
C:\test>py test.py
Enter n value: 999
Yes
while t!=0:
if t%10!=0:
break
c=c+1
t=t//10
C:\test>py test.py
Enter n value: 5
num: 5, fact: 120 and trailing zeros: 1
C:\test>py test.py
Enter n value: 6
num: 6, fact: 720 and trailing zeros: 1
C:\test>py test.py
Enter n value: 7
num: 7, fact: 5040 and trailing zeros: 1
C:\test>py test.py
Enter n value: 4
num: 4, fact: 24 and trailing zeros: 0
C:\test>py test.py
Enter n value: 10
num: 10, fact: 3628800 and trailing zeros: 2
def fun2(x,y):
return int(math.pow(x,y))
def fun3(x,y):
return x**y
x = int(input())
y = int(input())
print(fun1(x,y))
print(fun2(x,y))
print(fun3(x,y))
C:\test>py test.py
2
3
8
8
8
C:\test>py test.py
5
10
9765625
9765625
9765625
C:\test>py test.py
Enter any num: 12345
15
C:\test>py test.py
Enter any num: 0
0
C:\test>py test.py
Enter any num: 222
6
C:\test>py test.py
Enter any num: 333
9
C:\test>py test.py
Enter any num: 12345
6
C:\test>py test.py
Enter any num: 0
0
C:\test>py test.py
Enter any num: 222
6
C:\test>py test.py
Enter any num: 333
0
C:\test>py test.py
Enter any num: 12345
9
C:\test>py test.py
Enter any num: 0
0
C:\test>py test.py
Enter any num: 222
0
C:\test>py test.py
Enter any num: 333
9
C:\test>py test.py
Enter any num: 12345
10
C:\test>py test.py
Enter any num: 222
6
C:\test>py test.py
Enter any num: 666
0
def prime2(n):
for i in range(2,n):
if n%i==0:
return False
return True
for i in range(2,21):
print(f"{i} \t {prime1(i)} \t {prime2(i)}")
C:\test>py test.py
2 True True
3 True True
4 False False
5 True True
6 False False
7 True True
8 False False
9 False False
10 False False
11 True True
12 False False
13 True True
14 False False
15 False False
16 False False
17 True True
18 False False
19 True True
20 False False
L=[]
for i in range(1,n+1):
if n%i==0:
L.append(i)
print(L)
C:\test>py test.py
Enter any number: 10
[1, 2, 5, 10]
C:\test>py test.py
Enter any number: 11
[1, 11]
Ex:
---
n = int(input("Enter any number: "))
s=0
for i in range(1,n):
if n%i==0:
s=s+i
print("Yes" if s==n else "No")
C:\test>py test.py
Enter any number: 4
No
C:\test>py test.py
Enter any number: 5
No
C:\test>py test.py
Enter any number: 6
Yes
C:\test>py test.py
Enter any number: 24
No
C:\test>py test.py
Enter any number: 18
No
C:\test>py test.py
Enter any number: 28
Yes
if temp==s:
print(f"Yes {temp} is armstrong number")
else:
print(f"No {temp} is not armstrong number")
C:\test>py test.py
Enter any number: 123
No 123 is not armstrong number
C:\test>py test.py
Enter any number: 153
Yes 153 is armstrong number
import math
n = int(input("Enter any number: "))
temp = n
s = 0
while n!=0:
d = n % 10
s = s + math.factorial(d)
n = n // 10
if temp==s:
print(f"Yes {temp} is strong number")
else:
print(f"No {temp} is not strong number")
C:\test>py test.py
Enter any number: 123
No 123 is not strong number
C:\test>py test.py
Enter any number: 153
No 153 is not strong number
C:\test>py test.py
Enter any number: 145
Yes 145 is strong number
d1 = -1
d2 = 1
L = []
n = int(input("Enter how many numbers do you want?"))
for i in range(n):
d3 = d1 + d2
L.append(d3)
d1 = d2
d2 = d3
print(L)
C:\test>py test.py
Enter how many numbers do you want?10
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
d1 = -1
d2 = 0
d3 = 1
L = []
n = int(input("Enter how many numbers do you want?"))
for i in range(n):
d4 = d1 + d2 + d3
L.append(d4)
d1 = d2
d2 = d3
d3 = d4
print(L)
C:\test>py test.py
Enter how many numbers do you want?5
[0, 1, 2, 3, 6]
C:\test>py test.py
Enter how many numbers do you want?10
[0, 1, 2, 3, 6, 11, 20, 37, 68, 125]
Ex:
---
100 student records
growth of functions:
--------------------
1) constant time O(1)
---------------------
algorithm will return a constant time.
Ex:
Access Nth element from a list/array
push/pop operation in stack
insert/delete operation in queue
access element from hash table
etc
Ex:
linear search
finding max element in list/array
finding min element in list/array
travesal of a tree (in,pre,post,level)
display
etc
Ex:
binary search
inserting an element in a tree
Ex:
bubble sort
insertion sort
selection sort
etc
5) O(nlogn)
-----------
Algorithm will in n*logn, if the exeuction time of an alg is proportional
to product of input size and logarithm time of input size.
Ex:
---
merge sort
quick sort
heap sort
all divide and conquer based applications
etc
ab ---> "",a,b,ab
abc --> "",a,b,c,ab,ac,bc,abc
Ex: combinations
O(1)
O(n)
O(n2)
O(2^n)
O(logn)
O(nlogn)
O(n!) etc
Ex:
---
def fun(n):
c=0
i=0
while i<n:
c=c+1
i=i+1
return c
C:\test>py test.py
N=100, num of instructions O(n): 100
Ex:
---
def fun(n):
c=0
i=0
while i<n:
j=0
while j<n:
c=c+1
j=j+1
i=i+1
return c
C:\test>py test.py
N=100, num of instructions O(n^2): 10000
Ex:
---
def fun(n):
c=0
i=0
while i<n:
j=0
while j<n:
k = 0
while k<n:
c=c+1
k=k+1
j=j+1
i=i+1
return c
C:\test>py test.py
N=100, num of instructions O(n^3): 1000000
Ex:
---
def fun(n):
c=0
i=1
while i<n:
c=c+1
i=i*2
return c
C:\test>py test.py
N=100, num of instructions O(logn): 7
Ex:
---
def fun(n):
c=0
i=n
while i>=1:
c=c+1
print(i)
i=i//2
return c
C:\test>py test.py
100
50
25
12
6
3
1
N=100, num of instructions O(logn): 7
C:\test>py test.py
[10, 11, 12]
2457825071232
[10, 11, 12, 13]
2457825071232
Ex:
---
s = "PRAKASH"
print(s) #PRAKASH
ts=s.lower()
print(ts) #prakash
print(s) #PRAKASH
C:\test>py test.py
PRAKASH
prakash
PRAKASH
1. single quotes
2. double quotes
3. triple single quotes
4. triple double quotes
Ex:
---
s1 = 'Hai'
s2 = "Hi"
s3 = '''Bye'''
s4 = """Bi"""
print(s1,type(s1))
print(s2,type(s2))
print(s3,type(s3))
print(s4,type(s4))
C:\test>py test.py
Hai <class 'str'>
Hi <class 'str'>
Bye <class 'str'>
Bi <class 'str'>
index concept
-------------
we can use index concept and subscript combination to extract individual
characters from a string.
syntax:
s[index_value]
Ex:
---
s = "abc"
# 012
# 321
print(s) #abc
print(s[0]) #a
print(s[1]) #b
print(s[2]) #c
print(s[-1]) #c
print(s[-2]) #b
print(s[-3]) #a
Ex:
---
s = "abc"
# 012
# 321
print(s) #abc
print(s[0]) #a
print(s[1]) #b
print(s[2]) #c
print(s[5]) #IndexError
Ex:
---
s = "python"
#1st directly
print(s) #python
Ex:
---
s = "python"
# 012345
#index
print(s[0]) #p
print(s[1]) #y
print(s[2]) #t
print(s[3]) #h
print(s[4]) #o
print(s[5]) #n
Ex:
---
s = "python"
# 012345
#slice operator
#s[s:s:s]
#s --> start value
#s --> stop value
#s --> step value
print(s[0:6:1]) #python
print(s[0:6:2]) #pto
print(s[0:6:3]) #ph
Ex:
---
s = "abcdefg"
# 0123456
print(s) #abcdefg
print(s[0:7:1]) #abcdefg
print(s[0:7:2]) #aceg
print(s[0:7:3]) #adg
print(s[0:7:4]) #ae
print(s[2:5:1]) #cde
print(s[4:5:1]) #e
Note:
-----
1. the default value for start is 0
2. the default value for stop is length-1
3. the default value for step is 1
Ex:
---
s = "abcdefg"
# 0123456
print(s) #abcdefg
print(s[0:7:1]) #abcdefg
print(s[:7:1]) #abcdefg
print(s[0::1]) #abcdefg
print(s[0:7:]) #abcdefg
print(s[::])#abcdefg
Ex:
---
s = "abcdefg"
# +0123456
# -7654321
print(s) #abcdefg
print(s[-1:-8:-1]) #gfedcba
print(s[-3:-6:-1]) #edc
print(s[-1:-8:-2]) #geca
print(s[-1:-8:1]) #no output
print(s[5:2:1]) #no output
print(s[5:2:-1]) #fed
Note:
-----
1. the default value for start is -1
2. the default value for stop is -(length+1)
3. there is no default value for step
Ex:
---
s = "abcdefg"
# +0123456
# -7654321
print(s) #abcdefg
print(s[-1:-8:-1]) #gfedcba
print(s[:-8:-1]) #gfedcba
print(s[-1::-1]) #gfedcba
print(s[-1:-8:]) #no output
print(s[::]) #abcdefg
print(s[::-1]) #gfedcba
C:\test>py test.py
abcdefg
gfedcba
gfedcba
gfedcba
abcdefg
gfedcba
Ex:
---
s = "python"
#while loop
print(s) #python
index = 0
while index<len(s):
print(s[index])
index=index+1
C:\test>py test.py
python
p
y
t
h
o
n
Ex:
---
s = "python"
for ch in s:
print(ch)
C:\test>py test.py
python
p
y
t
h
o
n
Ex:
---
s1 = "abc"
s2 = "def"
print(s1+s2)
C:\test>py test.py
abcdef
Ex:
---
s = "abc"
print(s*3) #abcabcabc
print(2*s) #abcabc
C:\test>py test.py
abcabcabc
abcabc
Ex:
---
s = "abc"
print('a' in s) #True
print('f' in s) #False
print('w' not in s) #True
print('b' not in s) #False
C:\test>py test.py
True
False
True
False
Ex:
---
print("abc" < "mno") #True
print("pqr" < "abc") #False
print("abc" < "abc") #False
print("abc" <= "abc") #True
print("xyz" > "abc") #True
print("abc" > "abc") #False
print("abc" >= "abc") #True
print("abc" == "ijk") #False
print("abc" != "ijk") #True
Ex:
---
s = "prakash"
print(s) #prakash
print(len(s)) #7
print(max(s)) #s
print(min(s)) #a
print(sorted(s)) #['a','a','h','k','p','r','s']
print(sorted(s,reverse=True)) #['s','r','p','k','h','a','a']
Ex:
---
print(ord('a')) #97
print(ord('A')) #65
print(ord('0')) #48
Ex:
---
print(chr(97)) #a
print(chr(98)) #b
print(chr(65)) #A
print(chr(66)) #B
print(chr(48)) #0
print(chr(49)) #1
Ex:
---
s = "welcome TO pYtHoN PROGRamming"
print(s.count("a")) #4
print(s.count("ab")) #3
print(s.count("abc")) #2
print(s.count("pqr")) #0
print(s.replace("abc","pqr")) #pqrdpqraba
print(s.startswith("java")) #False
print(s.startswith("python")) #True
print(s.endswith("easy")) #True
print(s.endswith("difficult")) #False
print(s.index("is")) #7
print(s.index("was")) #Error
C:\test>py test.py
7
ValueError: substring not found
print(s.find("is")) #7
print(s.find("was")) #-1
sep.join(list) ---> it takes sep and joins each eleme with sep
--------------------------------------------------------------
L=['python', 'is', 'very', 'easy']
Ex:
---
L = [10, 23.556, True, 1+4j, "abc"]
print(L)
print(type(L))
C:\test>py test.py
[10, 23.556, True, (1+4j), 'abc']
<class 'list'>
Ex:
---
L1 = [10,20,30]
L2 = [40,50]
print(L1+L2) #[10,20,30,40,50]
Ex:
---
L = [10,20,30]
print(L*3) #[10,20,30,10,20,30,10,20,30]
print(2*L) #[10,20,30,10,20,30]
Ex:
---
L = [10,20,30]
print(10 in L) #True
print(100 in L) #False
print(20 not in L) #False
print(200 not in L) #True
Ex:
---
L1 = [10,20,30]
L2 = [10,40,50]
print(L1==L2) #False
print(L1!=L2) #True
print(L1<L2) #True
print(L1>L2) #False
print(L1<=L2) #True
print(L1>=L2) #False
nested list:
------------
a list obj within another list obj is called as nested list
Ex:
---
L = [10, 20, 30, [40, 50, 60, 70], 80, 90, 100]
# 0 1 2 3 4 5 6
print(L) #[10, 20, 30, [40, 50, 60, 70], 80, 90, 100]
print(L[0]) #10
print(L[1]) #20
print(L[2]) #30
print(L[3]) #[40, 50, 60, 70]
print(L[3][0]) #40
print(L[3][1]) #50
print(L[3][2]) #60
print(L[3][3]) #70
print(L[4]) #80
print(L[5]) #90
print(L[6]) #100
list aliasing:
--------------
providing alternative name for the existing list obj is called as list
aliasing
Ex:
---
L1 = [10, 20, 30]
L2 = L1
print(L1) #[10,20,30]
print(L2) #[10,20,30]
print(L1 is L2) #True
Ex:
---
L1 = [10, 20, 30]
L2 = L1
print(L1) #[10,20,30]
print(L2) #[10,20,30]
L1[1] = 888
print(L1) #[10,888,30]
print(L2) #[10,888,30]
cloning:
--------
it is used to create duplicate copy of list object
Ex:
---
L1 = [10, 20, 30]
L2 = L1.copy()
print(L1) #[10,20,30]
print(L2) #[10,20,30]
print(L1 is L2) #False
Ex:
---
L1 = [10, 20, 30]
L2 = L1.copy()
print(L1) #[10,20,30]
print(L2) #[10,20,30]
L1[1] = 888
print(L1) #[10,888,30]
print(L2) #[10,20,30]
list comprehension:
-------------------
easiest way to create list objects.
[]
append items or insert the items
Ex: convert each name present in the list into upper case
---------------------------------------------------------
L1 = ["Prakash","Kiran","Rohith"]
L2 = [i.upper() for i in L1]
print(L1) #["Prakash","Kiran","Rohith"]
print(L2) #["PRAKASH","KIRAN","ROHITH"]
Ex:
---
L = [1, 5, 2, 4, 3]
print(L) #[1,5,2,4,3]
print(len(L)) #5
print(max(L)) #5
print(min(L)) #1
print(sorted(L)) #[1,2,3,4,5]
print(sorted(L,reverse=True)) #[5,4,3,2,1]
print(sum(L)) #15
Ex:
---
L = [10, 20, 30]
print(L) #[10, 20, 30]
L.append(40)
L.append(50)
print(L) #[10, 20, 30, 40, 50]
insert(index,obj)
-----------------
it is used to add an object into the list at the given location
Ex:
---
L = [10, 20, 30]
print(L) #[10, 20, 30]
L.insert(0,99)
print(L) #[99,10, 20, 30]
remove(obj)
-----------
it is used to remove an obj from the list.
Ex:
---
L = [10, 20, 30, 40, 50]
print(L) #[10, 20, 30, 40, 50]
L.remove(30)
print(L) #[10, 20, 40, 50]
pop(index)
----------
it is used to remove an obj located at given index value
Ex:
---
L = [10, 20, 30, 40, 50]
print(L) #[10, 20, 30, 40, 50]
L.pop(1)
print(L) #[10, 30, 40, 50]
pop()
-----
it is used to remove an obj located at end of given list
Ex:
---
L = [10, 20, 30, 40, 50]
print(L) #[10, 20, 30, 40, 50]
L.pop()
print(L) #[10, 20, 30, 40]
clear()
--------
it is used to remove all the objects from the given list
Ex:
---
L = [10, 20, 30, 40, 50]
print(L) #[10, 20, 30, 40, 50]
L.clear()
print(L) #[]
index(obj)
----------
it returns location of the given object
Ex:
---
L = [10, 20, 30, 40, 50]
print(L) #[10, 20, 30, 40, 50]
print(L.index(10)) #0
print(L.index(30)) #2
print(L.index(50)) #4
count(obj)
----------
it is used to find the number of occurrences of given obj
Ex:
---
L = [10, 20, 30, 10, 20]
print(L) #[10, 20, 30, 40, 50]
print(L.count(10)) #2
print(L.count(20)) #2
print(L.count(30)) #1
print(L.count(40)) #0
reverse()
---------
it is used to reverse the list
Ex:
---
L = [10, 40, 30, 50, 20]
print(L) #[10, 40, 30, 50, 20]
L.reverse()
print(L) #[20, 50, 30, 40, 10]
sort()
------
it sorts the given list in asc order
Ex:
---
L = [10, 40, 30, 50, 20]
print(L) #[10, 40, 30, 50, 20]
L.sort()
print(L) #[10, 20, 30, 40, 50]
sort(reverse=True)
------------------
it sorts the given list in desc order
Ex:
---
L = [10, 40, 30, 50, 20]
print(L) #[10, 40, 30, 50, 20]
L.sort(reverse=True)
print(L) #[50, 40, 30, 20, 10]
Ex:
---
L = [10, 40, 30, 50, 20]
print(L) #[10, 40, 30, 50, 20]
print(sorted(L)) #[10, 20, 30, 40, 50]
print(L) #[10, 40, 30, 50, 20]
Ex:
---
L = [1, 2, [3, 4], 5]
print(L)
L.reverse()
print(L)
C:\test>py test.py
[1, 2, [3, 4], 5]
[5, [3, 4], 2, 1]
Ex:
---
T = (10, 23.556, True, 1+4j, "abc")
print(T)
print(type(T))
C:\test>py test.py
(10, 23.556, True, (1+4j), 'abc')
<class 'tuple'>
nested tuple:
------------
a tuple obj within another tuple obj is called as nested tuple
tuple aliasing:
--------------
providing alternative name for the existing tuple obj is called as tuple
aliasing
Ex:
---
a = 111
b = 222
c = 333
t = a,b,c #tuple packing
Ex:
---
t = (666,777,888,999)
a,b,c,d = t #tuple unpacking
Ex:
---
s = {111, 222, 333, 444, 555}
print(s)
print(type(s))
C:\test>py test.py
{555, 444, 333, 222, 111}
<class 'set'>
Ex:
---
s = {}
print(s)
print(type(s))
C:\test>py test.py
{}
<class 'dict'>
Ex:
---
s = set()
print(s)
print(type(s))
C:\test>py test.py
set()
<class 'set'>
Ex:
---
s = {111, 222, 333, 444, 555}
print(s)
for i in s:
print(i)
Ex:
---
s = {10, [20, 30, 40], 50, 60}
print(s)
Ex:
---
s = {10, 50, 20, 30}
Ex:
---
s = {10, 20, 30}
print(s) #{10,20,30}
s.add(40)
s.add(50)
print(s) #{10,20,30,40,50}
s.remove(obj)
-------------
it is used to remove an obj from set
Ex:
---
s = {10, 20, 30}
print(s) #{10,20,30}
s.remove(20)
print(s) #{10,30}
Ex:
---
s = {10, 20, 30}
print(s) #{10,20,30}
s.remove(40)
print(s) #{10,20, 30}
C:\test>py test.py
{10, 20, 30}
Traceback (most recent call last):
File "C:\test\test.py", line 3, in <module>
s.remove(40)
KeyError: 40
discard(obj)
------------
it is same as remove(), but is obj doesn't exists it wn't raise error
Ex:
---
s = {10, 20, 30}
print(s) #{10,20,30}
s.discard(40)
s.discard(20)
print(s) #{10,30}
clear()
-------
it removes all objs from the set
Ex:
---
s = {10, 20, 30}
print(s) #{10,20,30}
s.clear()
print(s) #set()
Ex:
---
d = {1:"One", 2:"Two", 3:"Three", 4:"Four"}
print(d)
print(type(d))
C:\test>py test.py
{1: 'One', 2: 'Two', 3: 'Three', 4: 'Four'}
<class 'dict'>
C:\test>
==> index concept is not allowed, but keys will act as index.
==> dupliate keys are not allowed but values can be duplicated.
Ex:
---
d = {1:"One", 2:"Two", 3:"Three", 4:"Four", 5:"Two"}
print(d)
C:\test>py test.py
{1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Two'}
C:\test>
Ex:
---
d = {1:"One", 2:"Two", 3:"Three", 4:"Four", 3:"Five"}
print(d)
C:\test>py test.py
{1: 'One', 2: 'Two', 3: 'Five', 4: 'Four'}
C:\test>
Ex:
---
d = {1:"One", 2:"Two", 3:"Three", 4:"Four", 5:"Five"}
print(d)
for i in d.items():
print(i)
C:\test>py test.py
{1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five'}
(1, 'One')
(2, 'Two')
(3, 'Three')
(4, 'Four')
(5, 'Five')
C:\test>
Ex:
---
d = {1:"One", 2:"Two", 3:"Three", 4:"Four", 5:"Five"}
print(d)
d[6] = "Six"
d[7] = "Seven"
print(d)
C:\test>py test.py
{1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five'}
{1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five', 6: 'Six', 7:
'Seven'}
del d[key]
----------
it is used to delete an item from the dict
Ex:
---
d = {1:"One", 2:"Two", 3:"Three", 4:"Four", 5:"Five"}
print(d)
del d[3]
print(d)
C:\test>py test.py
{1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five'}
{1: 'One', 2: 'Two', 4: 'Four', 5: 'Five'}
C:\test>
pop(key)
--------
it delete corresponding key and value pairs from the dict
Ex:
---
d = {1:"One", 2:"Two", 3:"Three", 4:"Four", 5:"Five"}
print(d)
d.pop(4)
print(d)
C:\test>py test.py
{1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five'}
{1: 'One', 2: 'Two', 3: 'Three', 5: 'Five'}
clear()
-------
it removes all the key and value pairs from the dict
Ex:
---
d = {1:"One", 2:"Two", 3:"Three", 4:"Four", 5:"Five"}
print(d)
d.clear()
print(d)
C:\test>py test.py
{1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five'}
{}
C:\test>
d.get(key)
----------
it returns value associated with given key, if not return None
Ex:
---
d = {1:"One", 2:"Two", 3:"Three", 4:"Four", 5:"Five"}
print(d)
print(d.get(4)) #Four
print(d.get(6)) #None
C:\test>py test.py
{1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five'}
Four
None
C:\test>
d.get(key,default)
------------------
it returns value associated with given key, if not return default val
Ex:
---
d = {1:"One", 2:"Two", 3:"Three", 4:"Four", 5:"Five"}
print(d)
print(d.get(4,"Not There")) #Four
print(d.get(6,"Not There")) #Not There
C:\test>py test.py
{1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five'}
Four
Not There
C:\test>
print(d)
print(d.keys())
print(d.values())
print(d.items())
C:\test>py test.py
{1: 'One', 2: 'Two', 3: 'Three', 4: 'Four', 5: 'Five'}
dict_keys([1, 2, 3, 4, 5])
dict_values(['One', 'Two', 'Three', 'Four', 'Five'])
dict_items([(1, 'One'), (2, 'Two'), (3, 'Three'), (4, 'Four'), (5,
'Five')])
dict comphrension:
------------------
Ex:
---
import math
C:\test>py test.py
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
{0: 0, 1: 1, 2: 8, 3: 27, 4: 64, 5: 125}
Programs on Strings:
--------------------
01. read and write string
-------------------------
s = input("Enter any string: ")
print(s)
C:\test>py test.py
Enter any string: welcome
welcome
C:\test>
02. read string and print characters present at +ve and -ve indexes
-------------------------------------------------------------------
s = input("Enter any string: ")
print(s)
index1 = 0
index2 = -1
C:\test>py test.py
Enter any string: abcd
abcd
index1:0, char:a, index2:-1, char:d
index1:1, char:b, index2:-2, char:c
index1:2, char:c, index2:-3, char:b
index1:3, char:d, index2:-4, char:a
index = 0
while index<len(s):
if index%2==0:
print(f"index:{index}, char:{s[index]}")
index=index+1
C:\test>py test.py
Enter any string: welcome
welcome
index:0, char:w
index:2, char:l
index:4, char:o
index:6, char:e
C:\test>
index = 0
while index<len(s):
if index%2!=0:
print(f"index:{index}, char:{s[index]}")
index=index+1
C:\test>py test.py
Enter any string: welcome
welcome
index:1, char:e
index:3, char:c
index:5, char:m
def fun(s):
return len(re.findall("[aeiou]",s))
C:\test>py test.py
Enter any string: welcome
welcome
['e', 'o', 'e']
C:\test>py test.py
Enter any string: welcome
welcome
3
C:\test>py test.py
Enter any string: programming
programming
3
def fun(s):
return len(re.findall("[^aeiou]",s))
C:\test>py test.py
Enter any string: welcome
welcome
4
C:\test>py test.py
Enter any string: programming
programming
8
def fun(s):
return len(re.findall("[a-zA-Z]",s))
C:\test>py test.py
Enter any string: welcome
welcome
7
C:\test>py test.py
Enter any string: wel#come@
wel#come@
7
C:\test>py test.py
Enter any string: WeL123COme
WeL123COm
def fun(s):
return len(re.findall("[0-9]",s))
C:\test>py test.py
Enter any string: acb123def
acb123def
3
C:\test>py test.py
Enter any string: abc$123^6u
abc$123^6u
4
C:\test>
def fun(s):
return len(re.findall("[ ]",s))
s = input("Enter any string: ")
print(s)
print(fun(s))
C:\test>py test.py
Enter any string: abc def xyz 123
abc def xyz 123
3
C:\test>
def fun(s):
return len(re.findall("[^a-zA-Z0-9 ]",s))
C:\test>py test.py
Enter any string: abc 345 d#e%f 7*9&8^0
abc 345 d#e%f 7*9&8^0
5
def fun2(s):
res = ""
for i in s:
res=i+res
return res
C:\test>py test.py
Enter any string: abcd
dcba
dcba
C:\test>py test.py
Enter any string: prakash
hsakarp
hsakarp
def fun2(s):
res = ""
for i in s:
res=res+chr(ord(i)-32)
return res
C:\test>py test.py
Enter any string: abc
ABC
ABC
C:\test>py test.py
Enter any string: prakash
PRAKASH
PRAKASH
def fun2(s):
res = ""
for i in s:
if i.isspace():
res=res+i
else:
res=res+chr(ord(i)+32)
return res
C:\test>py test.py
Enter any string: ABCDE
abcde
abcde
C:\test>py test.py
Enter any string: PYTHON AND JAVA
python and java
python and java
def fun2(s):
res = ""
for i in s:
if i.islower():
res = res + chr(ord(i)-32)
else:
res = res + chr(ord(i)+32)
return res
C:\test>py test.py
Enter any string: PyThOn
pYtHoN
pYtHoN
15. convert even indexed char into upper case and odd indexed char into
lower case
-----------------------------------------------------------------------
def fun(s):
res = ""
for i in range(len(s)):
if i%2==0:
res = res + s[i].upper()
else:
res = res + s[i].lower()
return res
C:\test>py test.py
Enter any string: python
PyThOn
16. convert odd indexed char into upper case and eve indexed char into
lower case
-----------------------------------------------------------------------
def fun(s):
res = ""
for i in range(len(s)):
if i%2!=0:
res = res + s[i].upper()
else:
res = res + s[i].lower()
return res
s=input()
print(s)
print(fun(s))
C:\test>py test.py
python is very easy to understand
python is very easy to understand
dnatsrednu ot ysae yrev si nohtyp
s=input()
print(s)
print(fun(s))
C:\test>py test.py
python is very easy to understand
python is very easy to understand
nohtyp is yrev easy ot understand
C:\test>py test.py
python is very easy to understand
python is very easy to understand
python si very ysae to dnatsrednu
s=input()
print(s)
print(fun(s))
C:\test>py test.py
python is very easy to understand
python is very easy to understand
Python Is Very Easy To Understand
21. convert each word first & last char into upper case
--------------------------------------------------------
def fun(s):
L = []
for i in s.split(" "):
L.append(i[0].upper()+i[1:len(i)-1]+i[-1].upper())
return ' '.join(L)
s=input()
print(s)
print(fun(s))
C:\test>py test.py
python is very easy to understand
python is very easy to understand
PythoN IS VerY EasY TO UnderstanD
C:\test>py test.py
python is very easy to understand
python is very easy to understand
pYTHOn is vERy eASy to uNDERSTANd
s=input()
print(s)
print(fun(s))
C:\test>py test.py
python was very easy to implement and understand
python was very easy to implement and understand
PYTHON was VERY EASY TO implement and UNDERSTAND
s=input()
print(s)
print(fun(s))
C:\test>py test.py
abc
abc
b
C:\test>py test.py
abcd
abcd
bc
C:\test>py test.py
abcde
abcde
c
C:\test>py test.py
abcdef
abcdef
cd
25. sort the string (sort the characters present in the given str)
------------------------------------------------------------------
def fun(s):
l = list(s)
l.sort()
return ''.join(l)
s=input()
print(s)
print(fun(s))
C:\test>py test.py
test
test
estt
C:\test>py test.py
demo
demo
demo
C:\test>py test.py
prakash
prakash
aahkprs
C:\test>py test.py
['pqr', 'mno', 'abc', 'xyz', 'ijk']
['abc', 'ijk', 'mno', 'pqr', 'xyz']
C:\test>py test.py
Enter string: welcome
welcome
welcom
C:\test>py test.py
Enter string: abcdabcaba
abcdabcaba
abcd
C:\test>py test.py
Enter string: welcome
welcome
wlcm
C:\test>py test.py
Enter string: prakash
prakash
prksh
C:\test>py test.py
Enter string: madam
madam
True
C:\test>py test.py
Enter string: liril
liril
True
abcdabcd
def fun(s1,s2):
if len(s1)!=len(s2):
return False
temp = s1+s1
return temp.find(s2)!=-1
C:\test>py test.py
Enter string: abcd
Enter string: bcda
True
C:\test>py test.py
Enter string: abcd
Enter string: cdab
True
C:\test>py test.py
Enter string: abcde
Enter string: bcade
False
C:\test>py test.py
Enter list of values: [10, 20, 30, 40, 50]
[10, 20, 30, 40, 50]
10
20
30
40
50
l = [1, 2, 3, 4, 5]
print(fun(l)) #1+2+3+4+5=15
C:\test>py test.py
15
C:\test>
print(fun([1, 2, 3, 4, 5]))
print(fun([]))
C:\test>py test.py
3.0
0.0
even,odd = fun()
print(even)
print(odd)
C:\test>py test.py
[0, 2, 4, 6, 8, 10]
[1, 3, 5, 7, 9]
C:\test>
5. get smaller elements from a list less then the given element x
-----------------------------------------------------------------
def fun(l,x):
return [i for i in l if i<x]
C:\test>py test.py
[9, 11, 15, 12, 3, 7, 14, 10]
[9, 3, 7]
C:\test>
print(fun())
C:\test>py test.py
[17, 2, 9, 12, 1, 4, 9, 10, 6, 9]
C:\test>py test.py
[14, 17, 3, 2, 13, 4, 10, 18, 3, 18]
C:\test>py test.py
[1, 9, 4, 15, 11, 6, 10, 19, 7, 14]
L = [1, 2, 3, 4, 5]
print(L) #[1, 2, 3, 4, 5]
fun(L)
print(L) #[5, 2, 3, 4, 1]
C:\test>py test.py
[1, 2, 3, 4, 5]
[5, 2, 3, 4, 1]
C:\test>
version2:
---------
def fun(L,start,end):
while start<=end:
L[start],L[end]=L[end],L[start]
start=start+1
end=end-1
print(fun([1,2,3,4,5],1)) #0
print(fun([1,2,3,4,5],5)) #4
print(fun([1,2,3,4,5],6)) #None
11. find the largest / max element in the list
----------------------------------------------
def fun(L):
if not L:
return None
m = L[0]
for i in range(1,len(L)):
if L[i]>m:
m = L[i]
return m
print(fun([1,3,2,5,4])) #5
print(fun([1,3,2,-5,4])) #4
print(fun([1])) #1
print(fun([])) #None
print(fun([1,3,2,5,4])) #1
print(fun([1,3,2,-5,4])) #-5
print(fun([1])) #1
print(fun([])) #None
def fun2(l):
if len(l)<=1:
return None
lar = fun1(l)
slar = None
for i in l:
if i!=lar:
if slar==None:
slar = i
else:
slar = max(slar,i)
return slar
print(fun2([1,3,2,5,4])) #4
print(fun2([1,3,2,-5,4])) #3
print(fun2([1])) #None
print(fun2([])) #None
print(fun([1,2,3,4,5])) #True
print(fun([1,2,5,3,4])) #False
l1 = [1, 3, 5, 2, 4]
l2 = [6, 8, 7, 9, 10]
l3 = fun(l1,l2)
print(l1) #[1, 3, 5, 2, 4]
print(l2) #[6, 8, 7, 9, 10]
print(l3) #[1, 3, 5, 2, 4, 6, 8, 7, 9, 10]
16. merge two list objects into third list and sort
---------------------------------------------------
def fun(l1,l2):
l=l1+l2
l.sort()
return l
l1 = [1, 3, 5, 2, 4]
l2 = [6, 8, 7, 9, 10]
l3 = fun(l1,l2)
print(l1) #[1, 3, 5, 2, 4]
print(l2) #[6, 8, 7, 9, 10]
print(l3) #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
l1 = [1, 2, 3, 4, 5]
l2 = [4, 5, 6, 7, 8]
print(fun(l1,l2)) #[1, 2, 3, 4, 5, 6, 7, 8]
l1 = [1, 2, 3, 4, 5]
l2 = [4, 5, 6, 7, 8]
print(fun(l1,l2)) #[4,5]
l = [1, 2, 3, 4, 5]
print(fun(l)) #[1, 3, 6, 10, 15]
version2:
---------
L = [1, 2, 3, 4, 5, 6]
print(L) #[1, 2, 3, 4, 5, 6]
#by using insertion and deletion
L.append(L.pop(0))
print(L) #[2, 3, 4, 5, 6, 1]
version3:
---------
def fun(L):
n = len(L)
x = L[0]
for i in range(1,n):
L[i-1] = L[i]
L[n-1] = x
L = [1, 2, 3, 4, 5, 6, 7]
print(L) #[1, 2, 3, 4, 5, 6, 7]
#by manual impl
fun(L)
print(L) #[2, 3, 4, 5, 6, 7, 1]
version2:
---------
L = [1, 2, 3, 4, 5, 6]
print(L) #[1, 2, 3, 4, 5, 6]
#by using insertion and deletion
L.insert(0,L.pop())
print(L) #[6, 1, 2, 3, 4, 5]
version3:
---------
def fun(L):
n = len(L)
x = L[n-1]
for i in range(n-1,0,-1):
L[i] = L[i-1]
L[0] = x
L = [1, 2, 3, 4, 5, 6, 7]
print(L) #[1, 2, 3, 4, 5, 6, 7]
#by manual impl
fun(L)
print(L) #[7, 1, 2, 3, 4, 5, 6]
version2:
---------
L = [1, 2, 3, 4, 5, 6, 7]
print(L) #[1, 2, 3, 4, 5, 6, 7]
d = 3
for i in range(0,d):
L.append(L.pop(0))
print(L) #[4, 5, 6, 7, 1, 2, 3]
version3:
---------
from collections import deque
L = [1, 2, 3, 4, 5, 6, 7]
print(L) #[1, 2, 3, 4, 5, 6, 7]
d = 2
dq = deque(L)
dq.rotate(-d) #-d left rotate
L = list(dq)
print(L) #[3, 4, 5, 6, 7, 1, 2]
version4:
---------
def reverse(L,b,e):
while b<e:
L[b],L[e] = L[e],L[b]
b=b+1
e=e-1
def fun(L,d):
n=len(L)
reverse(L,0,d-1)
reverse(L,d,n-1)
reverse(L,0,n-1)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9]
d = 2
print(L) #[1, 2, 3, 4, 5, 6, 7, 8, 9]
fun(L,d)
print(L) #[3, 4, 5, 6, 7, 8, 9, 1, 2]
version2:
---------
L = [1, 2, 3, 4, 5, 6, 7]
print(L) #[1, 2, 3, 4, 5, 6, 7]
d = 3
for i in range(0,d):
L.insert(0,L.pop(-1))
print(L) #[5, 6, 7, 1, 2, 3, 4]
version3:
---------
from collections import deque
L = [1, 2, 3, 4, 5, 6, 7]
print(L) #[1, 2, 3, 4, 5, 6, 7]
d = 2
dq = deque(L)
dq.rotate(d) #d right rotate
L = list(dq)
print(L) #[6, 7, 1, 2, 3, 4, 5]
version4:
---------
def reverse(L,b,e):
while b<e:
L[b],L[e] = L[e],L[b]
b=b+1
e=e-1
def fun(L,d):
n=len(L)
reverse(L,0,n-1)
reverse(L,0,d-1)
reverse(L,d,n-1)
L = [1, 2, 3, 4, 5, 6, 7, 8, 9]
d = 2
print(L) #[1, 2, 3, 4, 5, 6, 7, 8, 9]
fun(L,d)
print(L) #[8, 9, 1, 2, 3, 4, 5, 6, 7]
programs on matrices
~~~~~~~~~~~~~~~~~~~~
collection of rows and cols ----> matrix
1 2 3
4 5 6
7 8 9
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
C:\test>py test.py
Enter num of rows: 3
Enter num of cols: 3
1 2 3
4 5 6
7 8 9
1 2 3
4 5 6
7 8 9
def fun(L,m,n):
s=0
for i in range(m):
for j in range(n):
s=s+L[i][j]
return s
C:\test>py test.py
Enter num of rows: 3
Enter num of cols: 3
1 2 3
4 5 6
7 8 9
1 2 3
4 5 6
7 8 9
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def init(L,m,n):
for i in range(m):
TL = [0 for i in range(n)]
L.append(TL)
def addition(L1,m,n,L2,L3):
for i in range(m):
for j in range(n):
L3[i][j] = L1[i][j] + L2[i][j]
print()
printm(L1,m,n)
print()
printm(L2,m,n)
print()
printm(L3,m,n)
C:\test>py test.py
Enter num of rows: 2
Enter num of cols: 2
1 2
3 4
5 6
7 8
1 2
3 4
5 6
7 8
6 8
10 12
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def init(L,m,n):
for i in range(m):
TL = [0 for i in range(n)]
L.append(TL)
def subtraction(L1,m,n,L2,L3):
for i in range(m):
for j in range(n):
L3[i][j] = L1[i][j] - L2[i][j]
print()
printm(L1,m,n)
print()
printm(L2,m,n)
print()
printm(L3,m,n)
C:\test>py test.py
Enter num of rows: 2
Enter num of cols: 4
1 2 3 4
5 6 7 8
1 1 1 1
2 2 2 2
1 2 3 4
5 6 7 8
1 1 1 1
2 2 2 2
0 1 2 3
3 4 5 6
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def init(L,m,n):
for i in range(m):
TL = [0 for i in range(n)]
L.append(TL)
def multiplication(L1,m,n,L2,L3):
for i in range(m):
for j in range(n):
for k in range(n):
L3[i][j] = L3[i][j] + L1[i][k]*L2[k][j]
print("Matrix: A")
printm(L1,m,n)
print("Matrix: B")
printm(L2,m,n)
print("Matrix: C")
printm(L3,m,n)
C:\test>py test.py
Enter num of rows: 3
Enter num of cols: 3
1 2 3
4 5 6
7 8 9
1 0 0
0 1 0
0 0 1
Matrix: A
1 2 3
4 5 6
7 8 9
Matrix: B
1 0 0
0 1 0
0 0 1
Matrix: C
1 2 3
4 5 6
7 8 9
C:\test>py test.py
Enter num of rows: 2
Enter num of cols: 2
1 2
3 4
5 6
7 8
Matrix: A
1 2
3 4
Matrix: B
5 6
7 8
Matrix: C
19 22
43 50
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def fun(L,m,n):
for i in range(m):
s=0
for j in range(n):
s=s+L[i][j]
print(f"row: {i} and sum: {s}")
print("Matrix: A")
printm(L,m,n)
fun(L,m,n)
C:\test>py test.py
Enter num of rows: 3
Enter num of cols: 3
1 2 3
4 5 6
7 8 9
Matrix: A
1 2 3
4 5 6
7 8 9
row: 0 and sum: 6
row: 1 and sum: 15
row: 2 and sum: 24
def read(L,m,n):
for i in range(m):
TL = [int(i) for i in input().split()]
L.append(TL)
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def fun(L,m,n):
for i in range(m):
s=0
for j in range(n):
s=s+L[j][i]
print(f"col: {i} and sum: {s}")
print("Matrix: A")
printm(L,m,n)
fun(L,m,n)
C:\test>py test.py
Enter num of rows: 3
Enter num of cols: 3
1 2 3
4 5 6
7 8 9
Matrix: A
1 2 3
4 5 6
7 8 9
col: 0 and sum: 12
col: 1 and sum: 15
col: 2 and sum: 18
def fun(L,m,n):
s=0
for i in range(m):
s=s+L[i][i]
return s
print("Matrix: A")
printm(L,m,n)
print(fun(L,m,n))
C:\test>py test.py
Enter num of rows: 3
Enter num of cols: 3
1 2 3
4 5 6
7 8 9
Matrix: A
1 2 3
4 5 6
7 8 9
15
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def fun(L,m,n):
s=0
for i in range(m):
s=s+L[i][m-i-1]
return s
print("Matrix: A")
printm(L,m,n)
print(fun(L,m,n))
C:\test>py test.py
Enter num of rows: 3
Enter num of cols: 3
1 0 0
0 1 0
0 0 1
Matrix: A
1 0 0
0 1 0
0 0 1
1
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def printmm(L,m,n):
for i in range(m):
for j in range(n):
print(L[j][i],end=' ')
print()
print("Matrix: A")
printm(L,m,n)
print("Transpose Matrix: A")
printmm(L,m,n)
C:\test>py test.py
Enter num of rows: 3
Enter num of cols: 3
1 2 3
4 5 6
7 8 9
Matrix: A
1 2 3
4 5 6
7 8 9
Transpose Matrix: A
1 4 7
2 5 8
3 6 9
1 0 0
0 1 0
0 0 1 Yes
def read(L,m,n):
for i in range(m):
TL = [int(i) for i in input().split()]
L.append(TL)
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def identity(L,m,n):
for i in range(m):
for j in range(n):
if i==j and L[i][j]!=1:
return False
if i!=j and L[i][j]!=0:
return False
return True
print("Matrix: A")
printm(L,m,n)
print(identity(L,m,n))
C:\test>py test.py
Enter num of rows: 3
Enter num of cols: 3
1 2 3
4 5 6
7 8 9
Matrix: A
1 2 3
4 5 6
7 8 9
False
C:\test>py test.py
Enter num of rows: 3
Enter num of cols: 3
1 0 0
0 1 0
0 0 1
Matrix: A
1 0 0
0 1 0
0 0 1
True
row 1 and 3
7 8 9
4 5 6
1 2 3
def read(L,m,n):
for i in range(m):
TL = [int(i) for i in input().split()]
L.append(TL)
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def fun(L,m,n,x,y):
L[x-1],L[y-1] = L[y-1],L[x-1]
print("Matrix: A")
printm(L,m,n)
C:\test>py test.py
Enter num of rows: 4
Enter num of cols: 4
1 2 3 4
5 5 5 5
6 7 8 9
2 2 2 2
Matrix: A
1 2 3 4
5 5 5 5
6 7 8 9
2 2 2 2
Enter row1 value to swap: 1
Enter row2 value to swap: 3
Updated Matrix: A
6 7 8 9
5 5 5 5
1 2 3 4
2 2 2 2
1 and 2 col
2 1 3
5 4 6
8 7 9
def read(L,m,n):
for i in range(m):
TL = [int(i) for i in input().split()]
L.append(TL)
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def fun(L,m,n,x,y):
for i in range(m):
L[i][x-1],L[i][y-1] = L[i][y-1],L[i][x-1]
print("Matrix: A")
printm(L,m,n)
C:\test>py test.py
Enter num of rows: 4
Enter num of cols: 4
1 2 3 4
5 5 5 5
6 7 8 9
2 2 2 2
Matrix: A
1 2 3 4
5 5 5 5
6 7 8 9
2 2 2 2
Enter col1 value to swap: 1
Enter col2 value to swap: 4
Updated Matrix: A
4 2 3 1
5 5 5 5
9 7 8 6
2 2 2 2
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def fun(L,m,n):
for i in range(m):
L[i][i],L[i][m-i-1] = L[i][m-i-1],L[i][i]
m = int(input("Enter num of rows: "))
n = int(input("Enter num of cols: "))
L = []
read(L,m,n)
print("Matrix: A")
printm(L,m,n)
fun(L,m,n)
C:\test>py test.py
Enter num of rows: 4
Enter num of cols: 4
1 1 2 2
3 3 4 4
5 5 6 6
7 7 8 8
Matrix: A
1 1 2 2
3 3 4 4
5 5 6 6
7 7 8 8
Updated Matrix: A
2 1 2 1
3 4 3 4
5 6 5 6
8 7 8 7
def read(L,m,n):
for i in range(m):
TL = [int(i) for i in input().split()]
L.append(TL)
def printm(L,m,n):
for i in range(m):
for j in range(n):
print(L[i][j],end=' ')
print()
def printmm(L,m,n):
for i in range(m-1,-1,-1): #2,1,0
for j in range(n):
print(L[i][j],end=' ')
print()
def init(L,m,n):
for i in range(m):
TL = [0 for i in range(n)]
L.append(TL)
def fun(L,m,n):
#1st transpose
LL = []
init(LL,m,n)
for i in range(m):
for j in range(n):
LL[i][j] = L[j][i]
#2nd print in reverse w.r.t row
printmm(LL,m,n)
print("Matrix")
printm(L,m,n)
print("After 90 degrees rotation updated Matrix")
fun(L,m,n)
Ex:
---
def fun():
print("Good morning")
fun()
C:\test>py test.py
Good morning
Ex:
---
def fun():
print("Good morning")
fun()
fun()
Good morning
Good morning
Good morning
Good morning
RecursionError: maximum recursion depth exceeded while calling a Python
object
1. Finate Recursion
2. Infinate Recursion
InFinate Recursion
------------------
There is no proper condition to stop the recursion, it will keep on
executing, hence our internal stack is full it overflows, then python
raises error message saying Recursion Error.
Ex:
---
def fun():
print("Good morning")
fun()
fun()
Good morning
Good morning
Good morning
Good morning
RecursionError: maximum recursion depth exceeded while calling a Python
object
Finate Recursion:
-----------------
This recursion will stop at cetertain point by giving some condition.
this condition is called as base condition. then recursive call will end
at some point.
Ex:
---
def fun(n):
if n==0: #base condition
return
print("Good morning")
fun(n-1)
fun(5)
C:\test>py test.py
Good morning
Good morning
Good morning
Good morning
Good morning
C:\test>
base condition:
---------------
inside recursion, to stop recursion process at a finate steps we have to
construct a condition, such that out function call should terminate at
finate steps this condition inside the function is called as base
condition. based on our requirement we can change this condition..
1) direct recursion:
--------------------
def fun():
-----------
-----------
-----------
fun()
2) indirection recursion:
-------------------------
def fun1():
-----------
-----------
-----------
fun2()
def fun2():
-----------
-----------
-----------
fun1()
Applications of recursion
-------------------------
binary search algorithm
quick sort
merge sort
divide and conquer apps
factorial
prime
linked list
tree
graphs etc
tail recursion:
---------------
a recursive function is called tail recursion if the function does not
contain any statements after recursion call.
Ex:
---
def fun(n):
if n==0:
return
print(n)
fun(n-1) #recursion call
fun(5)
C:\test>py test.py
5
4
3
2
1
C:\test>
Ex:
---
def fun(n):
if n==0:
return
fun(n-1) #recursion call
print(n)
fun(5)
C:\test>py test.py
1
2
3
4
5
C:\test>
print(fun(4)) #0+1+2+3+4=10
print(fun(5)) #0+1+2+3+4+5=15
C:\test>py test.py
10
15
C:\test>
print(fun(4)) #1*2*3*4=24
print(fun(5)) #1*2*3*4*5=120
C:\test>py test.py
24
120
C:\test>
print(fun(1283)) #3+8+2+1=14
C:\test>py test.py
24
120
C:\test>
#0 1 1 2 3 5 8
for i in range(10):
print(fib(i),end=' ')
C:\test>py test.py
0 1 1 2 3 5 8 13 21 34
def fun(a,b):
if b==0:
return 1
return a*fun(a,b-1)
print(fun(2,0)) #1
print(fun(2,1)) #2
print(fun(2,2)) #4
print(fun(2,3)) #8
print(fun(2,8)) #256
C:\test>py test.py
1
2
4
8
256
print(fun(4,2)) #8
print(fun(3,2)) #6
print(fun(1,6)) #6
print(fun(8,0)) #0
print(prime(4,4//2)) #False
print(prime(5,5//2)) #True
print(prime(100,100//2)) #False
C:\test>py test.py
False
True
False
print(rev(123,3)) #321
print(rev(782307,6)) #703287
C:\test>py test.py
3204
7032843
for i in range(21):
print(f"{i}\t{fun(i)}")
C:\test>py test.py
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
16 10000
17 10001
18 10010
19 10011
20 10100
10. dec to oct
--------------
def fun(n):
if n==0:
return 0
return (n%8)+10*fun(n//8)
for i in range(21):
print(f"{i}\t{fun(i)}")
C:\test>py test.py
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 10
9 11
10 12
11 13
12 14
13 15
14 16
15 17
16 20
17 21
18 22
19 23
20 24
for i in range(21):
print(f"{i}\t{fun(i)}")
C:\test>py test.py
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12
13 13
14 14
15 15
16 10
17 11
18 12
19 13
20 14
print(fun("abcd")) #dcba
print(fun("abba")) #abba
def towers(n,src,temp,dest):
if n==1:
print(f"move disk {n} from {src} to {dest}")
return
towers(n-1,src,dest,temp)
print(f"move disk {n} from {src} to {dest}")
towers(n-1,temp,src,dest)
n=int(input())
towers(n,"S","T","D")
C:\test>py test.py
1
move disk 1 from S to D
C:\test>py test.py
2
move disk 1 from S to T
move disk 2 from S to D
move disk 1 from T to D
C:\test>py test.py
3
move disk 1 from S to D
move disk 2 from S to T
move disk 1 from D to T
move disk 3 from S to D
move disk 1 from T to S
move disk 2 from T to D
move disk 1 from S to D
C:\test>py test.py
4
move disk 1 from S to T
move disk 2 from S to D
move disk 1 from T to D
move disk 3 from S to T
move disk 1 from D to S
move disk 2 from D to T
move disk 1 from S to T
move disk 4 from S to D
move disk 1 from T to D
move disk 2 from T to S
move disk 1 from D to S
move disk 3 from T to D
move disk 1 from S to T
move disk 2 from S to D
move disk 1 from T to D
C:\test>py test.py
5
move disk 1 from S to D
move disk 2 from S to T
move disk 1 from D to T
move disk 3 from S to D
move disk 1 from T to S
move disk 2 from T to D
move disk 1 from S to D
move disk 4 from S to T
move disk 1 from D to T
move disk 2 from D to S
move disk 1 from T to S
move disk 3 from D to T
move disk 1 from S to D
move disk 2 from S to T
move disk 1 from D to T
move disk 5 from S to D
move disk 1 from T to S
move disk 2 from T to D
move disk 1 from S to D
move disk 3 from T to S
move disk 1 from D to T
move disk 2 from D to S
move disk 1 from T to S
move disk 4 from T to D
move disk 1 from S to D
move disk 2 from S to T
move disk 1 from D to T
move disk 3 from S to D
move disk 1 from T to S
move disk 2 from T to D
move disk 1 from S to D
C:\test>
def subsets(s,ans,index):
if index==len(s):
if len(ans)==0:
print("null")
else:
print(ans)
return
subsets(s,ans+s[index],index+1)
subsets(s,ans,index+1)
s=input()
ans=""
subsets(s,ans,0)
C:\test>py test.py
ab
ab
a
b
null
C:\test>py test.py
abc
abc
ab
ac
a
bc
b
c
null
def fun(s,ans):
if len(s)==0:
print(ans)
return
for i in range(len(s)):
fun(s[:i]+s[i+1:],ans+s[i])
s=input()
fun(s,"")
def gridways(i,j,n,m):
if i==n-1 and j==m-1:
return 1
elif i==n or j==m:
return 0
val1 = gridways(i+1,j,n,m)
val2 = gridways(i,j+1,n,m)
return val1 + val2
n = int(input())
m = int(input())
print(gridways(0,0,n,m))
C:\test>py test.py
2
2
2
C:\test>py test.py
3
3
6
C:\test>py test.py
4
4
20
Backtracking:
~~~~~~~~~~~~~
Introduction
------------
It is a method in which a solution is found by moving / searching through
large volume of data with some boundary condition.
Ex1: Number Locks
Ex2: Path Finding
Ex3: Sudoku Puzzle
Applications:
-------------
Number Locks
N-Queens
Sudoku
Rat in Maze etc
types of backtracking:
----------------------
1) decision based problems -------> Yes/No
2) optimized solution based problems ---> only one solution
3) enumeration based based problems ----> mutliple solutions
L = [0, 0, 0, 0, 0]
print(L) #[0, 0, 0, 0, 0]
change(L,0,1)
print(L) #[-1, 0, 1, 2, 3]
C:\test>py test.py
[0, 0, 0, 0, 0]
[1, 2, 3, 4, 5]
[-1, 0, 1, 2, 3]
N-Queens Problem:
-----------------
def safe(L,row,col):
#vertical up
i=row-1
while i>=0:
if L[i][col]=='Q':
return False
i=i-1
#dia left up
i = row - 1
j = col - 1
while i>=0 and j>=0:
if L[i][j]=='Q':
return False
i=i-1
j=j-1
#dia right up
i = row - 1
j = col + 1
while i>=0 and j<len(L):
if L[i][j]=='Q':
return False
i=i-1
j=j+1
return True
def nqueens(L,row):
if row==len(L):
global c
c=c+1
printboard(L)
return
for j in range(len(L)):
if safe(L,row,j):
L[row][j] = 'Q'
nqueens(L,row+1) #recursion
L[row][j] = 'X' #backtracking
def printboard(L):
print("--- chess board ---")
for i in range(len(L)):
for j in range(len(L)):
print(L[i][j],end=' ')
print()
print("-------------------")
c=0
n = 5
L = [['X' for i in range(n)] for i in range(n)]
#printboard(L)
nqueens(L,0)
print("Number of sol:",c)
C:\test>py test.py
--- chess board ---
Q X X X X
X X Q X X
X X X X Q
X Q X X X
X X X Q X
-------------------
--- chess board ---
Q X X X X
X X X Q X
X Q X X X
X X X X Q
X X Q X X
-------------------
--- chess board ---
X Q X X X
X X X Q X
Q X X X X
X X Q X X
X X X X Q
-------------------
--- chess board ---
X Q X X X
X X X X Q
X X Q X X
Q X X X X
X X X Q X
-------------------
--- chess board ---
X X Q X X
Q X X X X
X X X Q X
X Q X X X
X X X X Q
-------------------
--- chess board ---
X X Q X X
X X X X Q
X Q X X X
X X X Q X
Q X X X X
-------------------
--- chess board ---
X X X Q X
Q X X X X
X X Q X X
X X X X Q
X Q X X X
-------------------
--- chess board ---
X X X Q X
X Q X X X
X X X X Q
X X Q X X
Q X X X X
-------------------
--- chess board ---
X X X X Q
X Q X X X
X X X Q X
Q X X X X
X X Q X X
-------------------
--- chess board ---
X X X X Q
X X Q X X
Q X X X X
X X X Q X
X Q X X X
-------------------
Number of sol: 10
sudoku puzzle
-------------
def safe(sudoku,row,col,d):
#col
for i in range(9):
if sudoku[i][col]==d:
return False
#row
for i in range(9):
if sudoku[row][i]==d:
return False
#grid
sr = (row//3)*3
sc = (col//3)*3
for i in range(sr,sr+3):
for j in range(sc,sc+3):
if sudoku[i][j]==d:
return False
return True
def sudokusolver(sudoku,row,col):
if row==9 and col==0:
return True
nextrow = row
nextcol = col + 1
if col+1==9:
nextrow = row + 1
nextcol = 0
if sudoku[row][col]!=0:
return sudokusolver(sudoku,nextrow,nextcol)
for d in range(1,10):
if safe(sudoku,row,col,d):
sudoku[row][col] = d #Recursion
if sudokusolver(sudoku,nextrow,nextcol):
return True
sudoku[row][col]=0 #backtracking
return False
def printsudoku(sudoku):
for i in range(len(sudoku)):
for j in range(len(sudoku)):
print(sudoku[i][j],end=' ')
print()
'''
sudoku = [
[4, 0, 7, 0, 6, 8, 0, 3, 0],
[9, 0, 0, 3, 0, 2, 0, 0, 0],
[0, 0, 0, 1, 0, 7, 2, 4, 0],
[1, 0, 2, 6, 8, 0, 4, 9, 0],
[5, 0, 8, 0, 0, 4, 0, 2, 0],
[0, 6, 0, 0, 0, 0, 0, 8, 0],
[8, 7, 0, 0, 0, 6, 3, 0, 4],
[3, 0, 0, 8, 0, 1, 7, 6, 2],
[0, 0, 6, 0, 0, 0, 0, 1, 9],
]
'''
sudoku = [
[0, 0, 7, 0, 0, 0, 8, 0, 0],
[3, 0, 6, 1, 8, 2, 7, 4, 5],
[0, 8, 0, 5, 3, 7, 0, 0, 0],
[6, 7, 2, 0, 0, 5, 9, 0, 0],
[0, 4, 9, 2, 0, 8, 0, 1, 0],
[0, 3, 0, 4, 0, 6, 0, 0, 7],
[7, 6, 0, 8, 0, 0, 4, 0, 9],
[9, 0, 8, 0, 0, 3, 0, 0, 0],
[0, 0, 0, 6, 0, 0, 3, 0, 0],
]
printsudoku(sudoku)
if sudokusolver(sudoku,0,0):
print("solution existed")
printsudoku(sudoku)
else:
print("solution not existed")
C:\test>py test.py
0 0 7 0 0 0 8 0 0
3 0 6 1 8 2 7 4 5
0 8 0 5 3 7 0 0 0
6 7 2 0 0 5 9 0 0
0 4 9 2 0 8 0 1 0
0 3 0 4 0 6 0 0 7
7 6 0 8 0 0 4 0 9
9 0 8 0 0 3 0 0 0
0 0 0 6 0 0 3 0 0
solution existed
1 5 7 9 6 4 8 3 2
3 9 6 1 8 2 7 4 5
2 8 4 5 3 7 1 9 6
6 7 2 3 1 5 9 8 4
5 4 9 2 7 8 6 1 3
8 3 1 4 9 6 2 5 7
7 6 3 8 5 1 4 2 9
9 2 8 7 4 3 5 6 1
4 1 5 6 2 9 3 7 8
1) single node --> data field, pointer field pointing to next node
2) double node --> data field, pointer field pointing to next and prev
node
There are four types of linked lists are existed in data structures
The following are the various operations that can be perform on linked
list
Ex:
---
class dll:
class node:
def __init__(self,data,next=None,prev=None):
self.data = data
self.next = next
self.prev = prev
def __init__(self):
self.head = None
self.tail = None
self.count = 0
def size(self):
return self.count
def isempty(self):
return self.count==0
#insert at first
def insertatfirst(self,data):
newnode = self.node(data,None,None)
self.count = self.count + 1
if self.head==None:
self.head = newnode
self.tail = newnode
return
self.head.prev = newnode
newnode.next = self.head
self.head = newnode
return
#insert at last
def insertatlast(self,data):
newnode = self.node(data,None,None)
self.count = self.count + 1
if self.head ==None:
self.head = newnode
self.tail = newnode
return
newnode.prev = self.tail
self.tail.next = newnode
self.tail = newnode
return
#insert at location
def insertatlocation(self,index,data):
if index<0 or index>self.count:
print("out of range")
return
newnode = self.node(data,None,None)
self.count = self.count + 1
if index==0:
self.head.prev=newnode
newnode.next=self.head
self.head=newnode
return
if index==self.count-1:
newnode.prev = self.tail
self.tail.next = newnode
self.tail = newnode
return
temp1 = self.head
temp2 = None
i=0
while temp1!=None and i<index:
temp2 = temp1
temp1 = temp1.next
i=i+1
temp2.next = newnode
newnode.prev = temp2
newnode.next = temp1
temp1.prev = newnode
return
#search 1
def search1(self,data):
currnode = self.head
while currnode!=None:
if currnode.data==data:
return True
currnode = currnode.next
return False
#search 2
def search2(self,data):
currnode = self.head
i=0
currnode = self.head
while currnode!=None:
if currnode.data == data:
return i
currnode = currnode.next
i=i+1
return -1
#copy list
def copylist(self):
headnode = None
tailnode = None
tempnode = None
currnode = self.head
if currnode==None:
return None
headnode = self.node(currnode.data,None,None)
tailnode = headnode
currnode = currnode.next
while currnode!=None:
tempnode = self.node(currnode.data,None,None)
tailnode.next = tempnode
tempnode.prev = tailnode
tailnode = tempnode
currnode = currnode.next
newlist = dll()
newlist.head = headnode
return newlist
#reverse
def reverse(self):
temp = None
currnode = self.head
while currnode!=None:
temp = currnode.prev
currnode.prev = currnode.next
currnode.next = temp
currnode = currnode.prev
if temp!=None:
self.head = temp.prev
list = dll()
list.insertatfirst(444)
list.insertatfirst(333)
list.insertatfirst(222)
list.insertatfirst(111)
list.printlist()
list.reverse()
list.printlist()
Ex:
---
class csll:
class node:
def __init__(self,data,next=None):
self.data = data
self.next = next
def __init__(self):
self.tail = None
self.count = 0
def size(self):
return self.count
#insert at first
def insertatfirst(self,data):
newnode = self.node(data,None)
self.count = self.count + 1
if self.tail==None:
self.tail = newnode
newnode.next=newnode
return
newnode.next = self.tail.next
self.tail.next = newnode
return
#insert at last
def insertatlast(self,data):
newnode = self.node(data,None)
self.count = self.count + 1
if self.tail==None:
self.tail = newnode
newnode.next = newnode
return
newnode.next = self.tail.next
self.tail.next = newnode
self.tail = newnode
return
#displaying list
def printlist(self):
if self.tail == None:
print("list is empty")
return
currnode = self.tail.next
while currnode!=self.tail:
print(currnode.data,end=" => ")
currnode = currnode.next
print(currnode.data)
#delete at first
def deleteatfirst(self):
if self.count==0:
print("list is empty")
return
self.count = self.count - 1
if self.tail == self.tail.next:
self.tail = None
return
self.tail.next = self.tail.next.next
#delete at last
def deleteatlast(self):
if self.count==0:
print("list is empty")
return
self.count=self.count-1
if self.tail == self.tail.next:
self.tail=None
return
currnode = self.tail.next
while currnode.next!=self.tail:
currnode = currnode.next
currnode.next = self.tail.next
self.tail = currnode
list = csll()
list.insertatfirst(10)
list.insertatfirst(5)
list.insertatfirst(4)
list.insertatlast(20)
list.insertatlast(30)
list.printlist()
list.deleteatlast()
list.printlist()
class cdll:
class node:
def __init__(self,data,next=None,prev=None):
self.data = data
self.next = next
self.prev = prev
def __init__(self):
self.head = None
self.tail = None
self.count = 0
def size(self):
return self.count
#insert at first
def inseratfirst(self,data):
newnode = self.node(data,None,None)
self.count = self.count + 1
if self.tail==None:
self.tail = newnode
self.head = newnode
newnode.next = newnode
newnode.prev = newnode
return
newnode.next = self.head
newnode.prev = self.head.prev
self.head.prev = newnode
newnode.prev.next = newnode
self.head = newnode
return
#print list
def printlist(self):
if self.tail==None:
print("list is empty..")
return
currnode = self.tail.next
while currnode!=self.tail:
print(currnode.data,end=" => ")
currnode = currnode.next
print(currnode.data)
#insert at last
def inseratlast(self,data):
newnode = self.node(data,None,None)
self.count = self.count + 1
if self.tail == None:
self.tail = newnode
self.head = newnode
newnode.next = newnode
newnode.prev = newnode
return
newnode.next = self.tail.next
newnode.prev = self.tail
self.tail.next = newnode
newnode.next.prev = newnode
self.tail = newnode
#delete at first
def deleteatfirst(self):
if self.count==0:
print("list is empty...")
return
self.count = self.count - 1
if self.count==0:
self.tail = None
self.head = None
return
temp = self.head.next
temp.prev = self.tail
self.tail.next = temp
self.head = temp
#delete at last
def deleteatlast(self):
if self.count==0:
print("list is empty")
return
self.count = self.count - 1
if self.count == 0:
self.tail = None
self.head = None
return
temp = self.tail.prev
temp.next = self.head
self.head.prev = temp
self.tail = temp
list = cdll()
list.inseratfirst(1)
list.inseratfirst(2)
list.inseratfirst(3)
list.inseratfirst(4)
list.printlist()
list.deleteatlast()
list.printlist()
Sorting Algorithms:
~~~~~~~~~~~~~~~~~~~
Arranging the elements / objects in ascending order or descending is
called as sorting. we can do this sorting using predefined methods or we
can implement our own algorithms.
sort() method:
--------------
==> it is applicable only for list objects.
==> if we want to perform in asc order ------> L.sort()
==> if we want to perform in desc order -----> L.sort(reverse=True)
==> if we want to perform sorting based on our kye ---> L.sort(key=fun)
C:\test>
C:\test>py test.py
[10, 14, 12, 15, 13, 11]
[15, 14, 13, 12, 11, 10]
C:\test>
C:\test>py test.py
['HHH', 'BBB', 'PPP', 'CCC', 'KKK', 'AAA']
['AAA', 'BBB', 'CCC', 'HHH', 'KKK', 'PPP']
C:\test>py test.py
['HHH', 'BBB', 'PPP', 'CCC', 'KKK', 'AAA']
['PPP', 'KKK', 'HHH', 'CCC', 'BBB', 'AAA']
L = ["Ram","Prabas","Charan","Tarak","Arjun"]
print(L)
L.sort(key=fun)
print(L)
C:\test>py test.py
['Ram', 'Prabas', 'Charan', 'Tarak', 'Arjun']
['Ram', 'Tarak', 'Arjun', 'Prabas', 'Charan']
Ex: sorting string objects based on their length in desc order
--------------------------------------------------------------
def fun(s):
return len(s)
L = ["Ram","Prabas","Charan","Tarak","Arjun"]
print(L)
L.sort(key=fun,reverse=True)
print(L)
C:\test>py test.py
['Ram', 'Prabas', 'Charan', 'Tarak', 'Arjun']
['Prabas', 'Charan', 'Tarak', 'Arjun', 'Ram']
Ex: sort the student objects based on htno number in asc order
--------------------------------------------------------------
class student:
def __init__(self,htno,name,percentage):
self.htno = htno
self.name = name
self.percentage = percentage
def __str__(self):
return f"({self.htno}, {self.name}, {self.percentage})"
s1 = student(111,"Prakash",56.78)
s2 = student(333,"Sekhar",76.13)
s3 = student(222,"Sarath",98.34)
s4 = student(666,"Kiran",87.34)
s5 = student(444,"Durga",66.77)
def fun(s):
return s.htno
L.sort(key=fun)
print("AFTER SORTING")
for i in L:
print(i)
C:\test>py test.py
BEFORE SORTING
(111, Prakash, 56.78)
(333, Sekhar, 76.13)
(222, Sarath, 98.34)
(666, Kiran, 87.34)
(444, Durga, 66.77)
AFTER SORTING
(111, Prakash, 56.78)
(222, Sarath, 98.34)
(333, Sekhar, 76.13)
(444, Durga, 66.77)
(666, Kiran, 87.34)
Ex: sort the student objects based on htno number in desc order
--------------------------------------------------------------
class student:
def __init__(self,htno,name,percentage):
self.htno = htno
self.name = name
self.percentage = percentage
def __str__(self):
return f"({self.htno}, {self.name}, {self.percentage})"
s1 = student(111,"Prakash",56.78)
s2 = student(333,"Sekhar",76.13)
s3 = student(222,"Sarath",98.34)
s4 = student(666,"Kiran",87.34)
s5 = student(444,"Durga",66.77)
def fun(s):
return s.htno
L.sort(key=fun,reverse=True)
print("AFTER SORTING")
for i in L:
print(i)
C:\test>py test.py
BEFORE SORTING
(111, Prakash, 56.78)
(333, Sekhar, 76.13)
(222, Sarath, 98.34)
(666, Kiran, 87.34)
(444, Durga, 66.77)
AFTER SORTING
(666, Kiran, 87.34)
(444, Durga, 66.77)
(333, Sekhar, 76.13)
(222, Sarath, 98.34)
(111, Prakash, 56.78)
C:\test>
Ex: sort the student objects based on name in asc order
-------------------------------------------------------
class student:
def __init__(self,htno,name,percentage):
self.htno = htno
self.name = name
self.percentage = percentage
def __str__(self):
return f"({self.htno}, {self.name}, {self.percentage})"
s1 = student(111,"Prakash",56.78)
s2 = student(333,"Sekhar",76.13)
s3 = student(222,"Sarath",98.34)
s4 = student(666,"Kiran",87.34)
s5 = student(444,"Durga",66.77)
def fun(s):
return s.name
L.sort(key=fun)
print("AFTER SORTING")
for i in L:
print(i)
C:\test>py test.py
BEFORE SORTING
(111, Prakash, 56.78)
(333, Sekhar, 76.13)
(222, Sarath, 98.34)
(666, Kiran, 87.34)
(444, Durga, 66.77)
AFTER SORTING
(444, Durga, 66.77)
(666, Kiran, 87.34)
(111, Prakash, 56.78)
(222, Sarath, 98.34)
(333, Sekhar, 76.13)
def __init__(self,htno,name,percentage):
self.htno = htno
self.name = name
self.percentage = percentage
def __str__(self):
return f"({self.htno}, {self.name}, {self.percentage})"
s1 = student(111,"Prakash",56.78)
s2 = student(333,"Sekhar",76.13)
s3 = student(222,"Sarath",98.34)
s4 = student(666,"Kiran",87.34)
s5 = student(444,"Durga",66.77)
def fun(s):
return s.name
L.sort(key=fun,reverse=True)
print("AFTER SORTING")
for i in L:
print(i)
C:\test>py test.py
BEFORE SORTING
(111, Prakash, 56.78)
(333, Sekhar, 76.13)
(222, Sarath, 98.34)
(666, Kiran, 87.34)
(444, Durga, 66.77)
AFTER SORTING
(333, Sekhar, 76.13)
(222, Sarath, 98.34)
(111, Prakash, 56.78)
(666, Kiran, 87.34)
(444, Durga, 66.77)
Ex: sort the student objects based on percentage of marks in asc order
----------------------------------------------------------------------
class student:
def __init__(self,htno,name,percentage):
self.htno = htno
self.name = name
self.percentage = percentage
def __str__(self):
return f"({self.htno}, {self.name}, {self.percentage})"
s1 = student(111,"Prakash",56.78)
s2 = student(333,"Sekhar",76.13)
s3 = student(222,"Sarath",98.34)
s4 = student(666,"Kiran",87.34)
s5 = student(444,"Durga",66.77)
def fun(s):
return s.percentage
L.sort(key=fun)
print("AFTER SORTING")
for i in L:
print(i)
C:\test>py test.py
BEFORE SORTING
(111, Prakash, 56.78)
(333, Sekhar, 76.13)
(222, Sarath, 98.34)
(666, Kiran, 87.34)
(444, Durga, 66.77)
AFTER SORTING
(111, Prakash, 56.78)
(444, Durga, 66.77)
(333, Sekhar, 76.13)
(666, Kiran, 87.34)
(222, Sarath, 98.34)
Ex: sort the student objects based on percentage of marks in desc order
-----------------------------------------------------------------------
class student:
def __init__(self,htno,name,percentage):
self.htno = htno
self.name = name
self.percentage = percentage
def __str__(self):
return f"({self.htno}, {self.name}, {self.percentage})"
s1 = student(111,"Prakash",56.78)
s2 = student(333,"Sekhar",76.13)
s3 = student(222,"Sarath",98.34)
s4 = student(666,"Kiran",87.34)
s5 = student(444,"Durga",66.77)
def fun(s):
return s.percentage
L.sort(key=fun,reverse=True)
print("AFTER SORTING")
for i in L:
print(i)
C:\test>py test.py
BEFORE SORTING
(111, Prakash, 56.78)
(333, Sekhar, 76.13)
(222, Sarath, 98.34)
(666, Kiran, 87.34)
(444, Durga, 66.77)
AFTER SORTING
(222, Sarath, 98.34)
(666, Kiran, 87.34)
(333, Sekhar, 76.13)
(444, Durga, 66.77)
(111, Prakash, 56.78)
sorted() function:
------------------
it sorts the given data in asc / desc order and returns the data in the
form of a list, it wn't modify original data.
Ex:
---
L = [1, 5, 2, 4, 3]
print(L)
NL=sorted(L)
print(L)
print(NL)
C:\test>py test.py
[1, 5, 2, 4, 3]
[1, 5, 2, 4, 3]
[1, 2, 3, 4, 5]
Ex:
---
L = [1, 5, 2, 4, 3]
print(L)
NL=sorted(L,reverse=True)
print(L)
print(NL)
C:\test>py test.py
[1, 5, 2, 4, 3]
[1, 5, 2, 4, 3]
[5, 4, 3, 2, 1]
bubble sort
-----------
==> sort the data in asc or desc order.
==> stable sort.
==> first we will compare first element with second element, if largest
came then we have to swap.
==> we need to repeat this step for n times.
Ex: Implement bubble sort alg to sort the data in asc order
-----------------------------------------------------------
import random
#O(n2)
def bubblesort(L):
n=len(L)
for i in range(n-1):
for j in range(n-i-1):
if L[j]>L[j+1]:
L[j],L[j+1]=L[j+1],L[j]
L = []
for i in range(10):
L.append(random.randint(0,99))
print(L)
bubblesort(L)
print(L)
C:\test>py test.py
[2, 72, 99, 10, 31, 39, 35, 0, 85, 48]
[0, 2, 10, 31, 35, 39, 48, 72, 85, 99]
#O(n2)
def bubblesort(L):
n=len(L)
for i in range(n-1):
for j in range(n-i-1):
if L[j]<L[j+1]:
L[j],L[j+1]=L[j+1],L[j]
L = []
for i in range(10):
L.append(random.randint(0,99))
print(L)
bubblesort(L)
print(L)
C:\test>py test.py
[18, 45, 68, 67, 2, 31, 64, 61, 86, 20]
[86, 68, 67, 64, 61, 45, 31, 20, 18, 2]
selection sort
--------------
==> select an element and fix the position in its place.
==> first find min/max element move to the first or last location.
Ex:
---
import random
#O(n2)
def selectionsort(L):
n=len(L)
for i in range(n-1):
minIndex = i
for j in range(i+1,n):
if L[j] < L[minIndex]:
minIndex = j
L[i],L[minIndex]=L[minIndex],L[i]
L = []
for i in range(10):
L.append(random.randint(0,99))
print(L)
selectionsort(L)
print(L)
C:\test>py test.py
[77, 6, 5, 26, 21, 0, 34, 13, 64, 7]
[0, 5, 6, 7, 13, 21, 26, 34, 64, 77]
Ex:
import random
#O(n2)
def selectionsort(L):
n=len(L)
for i in range(n-1):
maxIndex = i
for j in range(i+1,n):
if L[j] > L[maxIndex]:
maxIndex = j
L[i],L[maxIndex]=L[maxIndex],L[i]
L = []
for i in range(10):
L.append(random.randint(0,99))
print(L)
selectionsort(L)
print(L)
C:\test>py test.py
[65, 20, 9, 98, 33, 75, 54, 85, 93, 26]
[98, 93, 85, 75, 65, 54, 33, 26, 20, 9]
Insertion sort
--------------
Ex:
---
import random
#O(n2)
def insertionsort(L):
n=len(L)
for i in range(1,n):
x = L[i]
j = i-1
while j>=0 and x<L[j]:
L[j+1] = L[j]
j=j-1
L[j+1]=x
L = []
for i in range(10):
L.append(random.randint(0,99))
print(L)
insertionsort(L)
print(L)
C:\test>py test.py
[64, 89, 84, 83, 59, 99, 50, 70, 65, 48]
[48, 50, 59, 64, 65, 70, 83, 84, 89, 99]
Ex:
---
import random
#O(n2)
def insertionsort(L):
n=len(L)
for i in range(1,n):
x = L[i]
j = i-1
while j>=0 and x>L[j]:
L[j+1] = L[j]
j=j-1
L[j+1]=x
L = []
for i in range(10):
L.append(random.randint(0,99))
print(L)
insertionsort(L)
print(L)
C:\test>py test.py
[52, 78, 52, 14, 78, 58, 47, 20, 2, 78]
[78, 78, 78, 58, 52, 52, 47, 20, 14, 2]
counting sort
-------------
def countingsort(L,k):
output = [0] * len(L)
count = [0] * k
for i in L:
count[i] = count[i] + 1
for i in range(1,k):
count[i] = count[i] + count[i-1]
for i in reversed(L):
output[count[i]-1] = i
count[i] = count[i]-1
for i in range(len(L)):
L[i] = output[i]
L = [1, 4, 4, 1, 0, 1]
print(L)
countingsort(L,5)
print(L)
C:\test>py test.py
[1, 4, 4, 1, 0, 1]
[0, 1, 1, 1, 4, 4]
C:\test>
radix sort
----------
Ex:
---
def countingsort(L,pos):
output = [0]*len(L)
count = [0] * 10
for i in range(0,len(L)):
index = (L[i]//pos)%10
count[index]=count[index]+1
for i in range(1,10):
count[i] = count[i] + count[i-1]
i=len(L)-1
while i>=0:
index= (L[i]//pos)%10
output[count[index]-1] = L[i]
count[index]=count[index]-1
i=i-1
for i in range(0,len(L)):
L[i] = output[i]
def radixsort(L):
m = max(L)
pos = 1
while m//pos>0:
countingsort(L,pos)
pos=pos*10
C:\test>py test.py
[319, 212, 6, 18, 100, 55]
[6, 18, 55, 100, 212, 319]
Ex:
Merge Sort
Quick Sort
Binary Search
etc
Ex1:
----
def merge(l1,l2):
l3 = l1 + l2
l3.sort()
return l3
C:\test>py test.py
[10, 15, 20]
[5, 6, 7, 30]
[5, 6, 7, 10, 15, 20, 30]
Ex2:
----
def merge(l1,l2):
l3 = []
m,n = len(l1),len(l2)
i,j=0,0
while i<m and j<n:
if l1[i]<l2[j]:
l3.append(l1[i])
i=i+1
else:
l3.append(l2[j])
j=j+1
while i<m:
l3.append(l1[i])
i=i+1
while j<n:
l3.append(l2[j])
j=j+1
return l3
C:\test>py test.py
[10, 15, 20]
[5, 6, 7, 30]
[5, 6, 7, 10, 15, 20, 30]
Ex:
---
def mergesort(L,lindex,rindex):
if rindex>lindex:
mid = (lindex + rindex)//2
mergesort(L,lindex,mid)
mergesort(L,mid+1,rindex)
merge(L,lindex,mid,rindex)
def merge(L,low,mid,high):
l = L[low:mid+1]
r = L[mid+1:high+1]
i=0
j=0
k=low
while i<len(l) and j<len(r):
if l[i]<r[j]:
L[k] = l[i]
i=i+1
k=k+1
else:
L[k] = r[j]
j=j+1
k=k+1
while i<len(l):
L[k]=l[i]
i=i+1
k=k+1
while j<len(r):
L[k]=r[j]
j=j+1
k=k+1
L = [4, 6, 1, 9, 2, 7, 3, 8, 5]
print(L)
mergesort(L,0,len(L)-1)
print(L)
C:\test>py test.py
[4, 6, 1, 9, 2, 7, 3, 8, 5]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Quick Sort:
-----------
def quicksort(l,low,high):
if high<=low:
return
pivot = l[low]
start = low
end = high
while low<high:
while l[low] <= pivot and low<high:
low = low + 1
while l[high] > pivot and low<=high:
high = high - 1
if low < high:
l[high],l[low] = l[low],l[high]
l[high],l[start] = l[start],l[high]
quicksort(l,start,high-1)
quicksort(l,high+1,end)
L = [4, 6, 1, 9, 2, 7, 3, 8, 5]
print(L)
quicksort(L,0,len(L)-1)
print(L)
C:\test>py test.py
[4, 6, 1, 9, 2, 7, 3, 8, 5]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
SEARCHING:
~~~~~~~~~~
searching is the process of fidning an item / object / element in a
collection of items the item may be keyword in file, book in lib, student
record in db, an obj in the list.
1. linear search
2. binary search
def linearsearch(L,key):
for i in range(len(L)):
if key==L[i]:
return i
return -1
L = []
for i in range(10):
L.append(random.randint(1,9))
print(L)
key = int(input("Enter element to search: "))
print(linearsearch(L,key))
C:\test>py test.py
[3, 4, 1, 4, 4, 9, 3, 3, 5, 2]
Enter element to search: 4
1
C:\test>py test.py
[7, 5, 6, 9, 6, 7, 5, 6, 2, 8]
Enter element to search: 6
2
C:\test>py test.py
[7, 1, 2, 1, 1, 1, 9, 4, 6, 1]
Enter element to search: 3
-1
def linearsearch(L,key):
for i in range(len(L)-1,0,-1):
if key==L[i]:
return i
return -1
L = []
for i in range(10):
L.append(random.randint(1,9))
print(L)
key = int(input("Enter element to search: "))
print(linearsearch(L,key))
C:\test>py test.py
[1, 1, 7, 3, 2, 8, 2, 3, 5, 3]
Enter element to search: 3
9
C:\test>py test.py
[1, 5, 8, 2, 5, 1, 2, 6, 4, 6]
Enter element to search: 5
4
C:\test>py test.py
[1, 9, 2, 3, 1, 8, 8, 8, 5, 7]
Enter element to search: 4
-1
def linearsearch(L,key):
TL = []
for i in range(len(L)):
if key==L[i]:
TL.append(i)
return TL[0:2]
L = []
for i in range(10):
L.append(random.randint(1,9))
print(L)
key = int(input("Enter element to search: "))
print(linearsearch(L,key))
C:\test>py test.py
[9, 9, 1, 3, 8, 3, 6, 3, 6, 4]
Enter element to search: 9
[0, 1]
C:\test>py test.py
[9, 6, 3, 5, 1, 9, 9, 7, 8, 3]
Enter element to search: 9
[0, 5]
def linearsearch(L,key):
TL = []
for i in range(len(L)):
if key==L[i]:
TL.append(i)
return TL
L = []
for i in range(10):
L.append(random.randint(1,9))
print(L)
key = int(input("Enter element to search: "))
print(linearsearch(L,key))
C:\test>py test.py
[6, 2, 1, 3, 3, 6, 2, 6, 9, 1]
Enter element to search: 1
[2, 9]
C:\test>py test.py
[6, 6, 5, 6, 6, 2, 1, 1, 3, 6]
Enter element to search: 6
[0, 1, 3, 4, 9]
C:\test>py test.py
[9, 5, 4, 7, 1, 6, 8, 4, 7, 7]
Enter element to search: 5
[1]
C:\test>py test.py
[1, 7, 7, 6, 4, 5, 2, 8, 7, 5]
Enter element to search: 9
[]
def binarysearch(L,key):
low = 0
high = len(L)-1
while low<=high:
mid = (low+high)//2
if key==L[mid]:
return mid
elif key<L[mid]:
high = mid-1
else:
low = mid+1
return -1
L = []
for i in range(10):
L.append(random.randint(10,99))
L.sort()
print(L)
key = int(input("Enter element to search: "))
print(binarysearch(L,key))
C:\test>py test.py
[16, 21, 27, 58, 61, 72, 90, 93, 95, 99]
Enter element to search: 90
6
C:\test>py test.py
[15, 23, 25, 31, 34, 57, 66, 69, 71, 75]
Enter element to search: 80
-1
def binarysearch(L,key,low,high):
if low>high:
return -1
mid = (low+high)//2
if key==L[mid]:
return mid
elif key<L[mid]:
return binarysearch(L,key,low,mid-1)
else:
return binarysearch(L,key,mid+1,high)
L = []
for i in range(10):
L.append(random.randint(10,99))
L.sort()
print(L)
key = int(input("Enter element to search: "))
print(binarysearch(L,key,0,len(L)-1))
C:\test>py test.py
[25, 30, 32, 32, 49, 56, 58, 68, 69, 76]
Enter element to search: 58
6
C:\test>py test.py
[15, 23, 23, 49, 57, 66, 71, 87, 89, 93]
Enter element to search: 15
0
C:\test>py test.py
[21, 44, 55, 58, 64, 65, 67, 75, 76, 98]
Enter element to search: 98
9
C:\test>py test.py
[14, 22, 26, 27, 42, 71, 73, 77, 84, 97]
Enter element to search: 99
-1
def binarysearch(L,key,low,high):
if low>high:
return -1
mid = (low+high)//2
if key==L[mid]:
return mid
elif key<L[mid]:
return binarysearch(L,key,low,mid-1)
else:
return binarysearch(L,key,mid+1,high)
L = []
for i in range(10):
L.append(random.randint(10,99))
L.sort()
print(L)
key = int(input("Enter element to search: "))
print(binarysearch(L,key,0,len(L)//2-1))
C:\test>py test.py
[19, 20, 45, 47, 53, 55, 61, 69, 76, 77]
Enter element to search: 76
-1
C:\test>py test.py
[10, 15, 16, 25, 38, 40, 43, 65, 90, 95]
Enter element to search: 38
4
C:\test>py test.py
[12, 32, 32, 55, 55, 58, 80, 81, 87, 99]
Enter element to search: 58
-1
def binarysearch(L,key,low,high):
if low>high:
return -1
mid = (low+high)//2
if key==L[mid]:
return mid
elif key<L[mid]:
return binarysearch(L,key,low,mid-1)
else:
return binarysearch(L,key,mid+1,high)
L = []
for i in range(10):
L.append(random.randint(10,99))
L.sort()
print(L)
key = int(input("Enter element to search: "))
print(binarysearch(L,key,len(L)//2,len(L)-1))
C:\test>py test.py
[17, 22, 25, 28, 36, 41, 47, 60, 73, 87]
Enter element to search: 17
-1
C:\test>py test.py
[12, 12, 14, 17, 26, 51, 59, 65, 81, 93]
Enter element to search: 51
5
C:\test>py test.py
[11, 17, 25, 42, 44, 45, 56, 60, 61, 73]
Enter element to search: 44
-1
C:\test>py test.py
[14, 27, 47, 50, 51, 51, 54, 66, 91, 96]
Enter element to search: 96
9
def binarysearch(L,key,low,high):
if low>high:
return -1
mid = (low+high)//2
if key==L[mid]:
return mid
elif key<L[mid]:
return binarysearch(L,key,low,mid-1)
else:
return binarysearch(L,key,mid+1,high)
L = []
for i in range(10):
L.append(random.randint(10,99))
L.sort()
print(L)
key = int(input("Enter element to search: "))
start = int(input("Enter start value: "))
end = int(input("Enter end value: "))
print(binarysearch(L,key,start,end))
C:\test>py test.py
[34, 35, 38, 53, 59, 75, 76, 88, 89, 91]
Enter element to search: 3
Enter start value: 3
Enter end value: 5
-1
C:\test>py test.py
[16, 19, 21, 36, 56, 58, 68, 72, 94, 99]
Enter element to search: 56
Enter start value: 3
Enter end value: 5
4
C:\test>py test.py
[14, 15, 25, 57, 63, 70, 90, 93, 95, 96]
Enter element to search: 3
Enter start value: 3
Enter end value: 5
-1
C:\test>py test.py
[13, 24, 26, 46, 56, 59, 60, 66, 70, 96]
Enter element to search: 96
Enter start value: 3
Enter end value: 7
-1
C:\test>py test.py
[11, 25, 28, 56, 61, 65, 71, 73, 74, 95]
Enter element to search: 25
Enter start value: 1
Enter end value: 4
1
Ex:
stack of plats
disks in the rack
function calls are stored in stack
web page navigation
parenthesis balancing
reversing items
expressions conversion
expr eval
undo/redo
forward/backward
etc
implementation of stack
-----------------------
container and top
when an obj is inserted into stack, top variable will be increment by one
unit
when an obj is deleted from stack, top variable will be decremented by
one unit
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)) #4
print(len(L)==0) #False
C:\test>py test.py
[]
[111, 222, 333, 444, 555]
555
[111, 222, 333, 444, 555]
[111, 222, 333, 444]
4
False
C:\test>py test.py
deque([])
deque([10, 20, 30, 40, 50, 60])
60
deque([10, 20, 30, 40, 50])
def __init__(self):
self.s = []
def isempty(self):
return len(self.s)==0
def size(self):
return len(self.s)
def push(self,data):
self.s.append(data)
def pop(self):
return self.s.pop()
def display(self):
print(self.s)
def peek(self):
return self.s[-1]
s = stack()
s.push(10)
s.push(20)
s.push(30)
s.display()
print(s.peek())#30
print(s.pop()) #30
s.display() #[10,20]
C:\test>py test.py
[10, 20, 30]
30
30
[10, 20]
C:\test>
class node:
def __init__(self,data,next=None):
self.data = data
self.next = next
def __init__(self):
self.head = None
self.count = 0
def isempty(self):
return self.count==0
def size(self):
return self.count
def peek(self):
if self.isempty():
print("list is empty")
return
return self.head.data
def push(self,data):
self.head = self.node(data,self.head)
self.count = self.count + 1
def pop(self):
if self.isempty():
print("stack is empty")
return
val = self.head.data
self.count = self.count - 1
self.head = self.head.next
return val
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()
s = stack()
s.push(100)
s.push(200)
s.push(300)
s.display()
print(s.pop()) #300
s.display()
print(s.peek()) #200
print(s.isempty()) #True
print(s.size()) #2
C:\test>py test.py
300 200 100
300
200 100
200
False
2
Stack.py
--------
class stack:
class node:
def __init__(self,data,next=None):
self.data = data
self.next = next
def __init__(self):
self.head = None
self.count = 0
def isempty(self):
return self.count==0
def size(self):
return self.count
def peek(self):
if self.isempty():
print("list is empty")
return
return self.head.data
def push(self,data):
self.head = self.node(data,self.head)
self.count = self.count + 1
def pop(self):
if self.isempty():
print("stack is empty")
return
val = self.head.data
self.count = self.count - 1
self.head = self.head.next
return val
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()
class student:
def __init__(self,sid,sname):
self.sid = sid
self.sname = sname
def __str__(self):
return f"({self.sid}, {self.sname})"
s1 = student(1,"AAA")
s2 = student(2,"BBB")
s3 = student(5,"UUU")
s4 = student(3,"WWW")
s5 = student(4,"CCC")
stk = stack()
stk.push(s1)
stk.push(s2)
stk.push(s3)
stk.push(s4)
stk.push(s5)
stk.display()
print(stk.pop())
stk.display()
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()
s.push(111)
s.push(444)
s.push(666)
s.display()
sortedinsert(s,555)
s.display()
sortedinsert(s,222)
s.display()
C:\test>py test.py
666 444 111
666 555 444 111
666 555 444 222 111
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(10)
s.push(40)
s.push(60)
s.push(30)
s.push(50)
s.push(20)
s.display()
sortstack(s)
s.display()
C:\test>py test.py
20 50 30 60 40 10
60 50 40 30 20 10
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() #333 222 111 444
bottominsert(s,999)
s.display() #333 222 111 444 999
reverse stack
-------------
from stack import *
def bottominsert(s,data):
if s.isempty():
s.push(data)
else:
temp = s.pop()
bottominsert(s,data)
s.push(temp)
def reversestack(s):
if not s.isempty():
temp = s.pop()
reversestack(s)
bottominsert(s,temp)
s = stack()
s.push(444)
s.push(111)
s.push(222)
s.push(333)
s.display() #333 222 111 444
reversestack(s)
s.display() #444 111 222 333
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(11)
s.push(22)
s.push(33)
s.display() #33 22 11
reversestack(s)
s.display() #11 22 33
def reversestack(s,k):
q = Queue(maxsize=6)
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(11)
s.push(22)
s.push(33)
s.push(44)
s.push(55)
s.push(66)
s.display() #66 55 44 33 22 11
reversestack(s,3)
s.display() #44 55 66 33 22 11
balanced paranethsis
--------------------
() True
[] True
{} True
([]) True
([}) False
([)] False
def balanced(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("()")) #True
print(balanced("([])")) #True
print(balanced("([)]")) #False
print(balanced("([{}])")) #True
print(balanced("([{]})")) #False
1. infix expressions
2. postfix expressions
3. prefix expressions
Ex:
a+b ---> ab+
a+b*c -> abc*+
(a+b)*c-> ab+c*
def infix_to_postfix_conversion(s):
stack = []
tokens=list(s)
result = ""
for item in tokens:
if item in "+-*/":
while len(stack)!=0 and precedence(item) <=
precedence(stack[-1]):
result = result + stack.pop()
stack.append(item)
elif item =='(':
stack.append('(')
elif item==')':
temp = None
while len(stack)!=0 and temp!='(':
temp = stack.pop()
if temp!='(':
result = result + temp
else:
result = result + item
while len(stack)!=0:
result = result + stack.pop()
return result
print(infix_to_postfix_conversion("a+b")) #ab+
print(infix_to_postfix_conversion("a+b-c*d")) #ab+cd*-
print(infix_to_postfix_conversion("a+(b-c)*d")) #abc-d*+
Ex:
a+b
1. b+a
2. -
3. ba+
4. +ab
Ex:a+b*c
1. c*b+a
2. -
3. cb*a+
4. +a*bc
def infix_to_postfix_conversion(s):
stack = []
tokens=list(s)
result = ""
for item in tokens:
if item in "+-*/":
while len(stack)!=0 and precedence(item) <=
precedence(stack[-1]):
result = result + stack.pop()
stack.append(item)
elif item =='(':
stack.append('(')
elif item==')':
temp = None
while len(stack)!=0 and temp!='(':
temp = stack.pop()
if temp!='(':
result = result + temp
else:
result = result + item
while len(stack)!=0:
result = result + stack.pop()
return result
def replace(s):
ss=""
for i in s:
if i=='(':
ss=ss+')'
elif i==')':
ss=ss+'('
else:
ss=ss+i
return ss
def infix_to_prefix_conversion(exp):
exp = exp[::-1]
exp = replace(exp)
exp = infix_to_postfix_conversion(exp)
exp = exp[::-1]
return exp
print(infix_to_prefix_conversion("a+b")) #ab+
print(infix_to_prefix_conversion("a+b-c*d")) #+a-b*cd
print(infix_to_prefix_conversion("a+(b-c)*d")) #+a*-bcd
steps:
------
1. create a stack to store operands
2. scan the expr from left to right and do the following
def infix_to_postfix_conversion(s):
stack = []
tokens=list(s)
result = ""
for item in tokens:
if item in "+-*/":
while len(stack)!=0 and precedence(item) <=
precedence(stack[-1]):
result = result + stack.pop()
stack.append(item)
elif item =='(':
stack.append('(')
elif item==')':
temp = None
while len(stack)!=0 and temp!='(':
temp = stack.pop()
if temp!='(':
result = result + temp
else:
result = result + item
while len(stack)!=0:
result = result + stack.pop()
return result
def replace(s):
ss=""
for i in s:
if i=='(':
ss=ss+')'
elif i==')':
ss=ss+'('
else:
ss=ss+i
return ss
def infix_to_prefix_conversion(exp):
exp = exp[::-1]
exp = replace(exp)
exp = infix_to_postfix_conversion(exp)
exp = exp[::-1]
return exp
def postfix_eval(exp):
stack = []
tokens = list(exp)
for token in tokens:
if token=='+':
n1 = stack.pop()
n2 = stack.pop()
stack.append(n1+n2)
elif token=='-':
n1 = stack.pop()
n2 = stack.pop()
stack.append(n1-n2)
elif token=='*':
n1 = stack.pop()
n2 = stack.pop()
stack.append(n1*n2)
elif token=='/':
n1 = stack.pop()
n2 = stack.pop()
stack.append(n1/n2)
else:
stack.append(int(token))
return stack.pop()
print(postfix_eval(infix_to_postfix_conversion("1+2"))) #3
print(postfix_eval(infix_to_postfix_conversion("1+2*3"))) #7
Introduction:
-------------
==> First - In - First - Out (FIFO)
==> front and rear
==> front is always used to access/delete
==> rear is always used to insert
Operations on Queue:
--------------------
The following are the very common operations that can be performed on Q
1. enque or insert
2. dequeue or delete
3. getFront
4. getRear
5. isempty
6. size
7. display
Applications:
-------------
1. Single Resource and Multiple Consumers (QUEUE)
2. Operating Systems
3. Printing Queue
4. Computer Networks etc
1. using list
-------------
q = []
print(len(q)==0) #True
q.append(10)
q.append(20)
q.append(30)
print(q) #[10, 20, 30]
print(len(q)==0) #False
print(q[0]) #front->10
print(q[-1]) #rear -> 30
print(q.pop(0)) #10
print(q) #[20, 30]
print(q.pop(0)) #20
print(q) #[30]
2. collections.deque
--------------------
from collections import deque
q = deque()
print(len(q)==0) #True
q.append(111)
q.append(222)
q.append(333)
print(len(q)==0) #False
print(q) #[111, 222, 333]
print(q[0]) #111
print(q[-1]) #333
print(q.popleft()) #111
print(q) #[222, 333]
3. queue.Queue
--------------
from queue import Queue
q = Queue()
print(q.qsize()) #0
print(q.empty()) #True
q.put(11)
q.put(22)
q.put(33)
q.put(44)
print(q.qsize()) #4
print(q.empty()) #False
print(q)
print(q.get()) #11
print(q.get()) #11
def __init__(self,cap):
self.q = [None]*cap
self.cap = cap
self.count = 0
def isfull(self):
return self.count==self.cap
def isempty(self):
return self.count==0
def size(self):
return self.count
def display(self):
if self.isempty():
print("q is empty")
return
for i in range(self.count):
print(self.q[i],end=" ")
print()
def delete(self):
if self.isempty():
print("q is empty")
return
res = self.q[0]
for i in range(self.count-1):
self.q[i] = self.q[i+1]
self.count = self.count-1
return res
def insert(self,data):
if self.isfull():
print("q is full")
return
self.q[self.count] = data
self.count = self.count + 1
q = queue(5)
print(q.size()) #0
print(q.isempty()) #True
print(q.isfull()) #False
q.insert(10)
q.insert(20)
q.insert(30)
q.insert(40)
q.display() #10 20 30 40
q.insert(50)
q.insert(60)
q.display() #10 20 30 40 50
print(q.delete()) #10
q.display() #20 30 40 50
q.insert(60)
print(q.size()) #4
print(q.isempty()) #False
print(q.isfull()) #True
C:\test>py test.py
0
True
False
10 20 30 40
q is full
10 20 30 40 50
10
20 30 40 50
5
False
True
class MyQueue:
class Node:
def __init__(self,data):
self.data = data
self.next = None
def __init__(self):
self.front = None
self.rear = None
self.count = 0
def size(self):
return self.count
def isempty(self):
return self.count==0
def getfront(self):
return self.front.data
def getrear(self):
return self.rear.data
def display(self):
if self.isempty():
print("Q is empty")
return
curr = self.front
while curr!=None:
print(curr.data,end=" ")
curr = curr.next
print()
def insert(self,data):
newnode = self.Node(data)
if self.rear==None:
self.front = newnode
else:
self.rear.next = newnode
self.rear = newnode
self.count = self.count + 1
def delete(self):
if self.isempty():
print("Q is empty")
return
res = self.front.data
self.front = self.front.next
if self.front==None:
self.rear = None
self.count = self.count - 1
return res
q = MyQueue()
print(q.isempty()) #True
print(q.size()) #0
q.insert(10)
q.insert(20)
q.insert(30)
q.display() #10 20 30
print(q.isempty()) #False
print(q.size()) #3
print(q.delete())
q.display() #20 30
print(q.isempty()) #False
print(q.size()) #2
C:\test>py test.py
True
0
10 20 30
False
3
10
20 30
False
2
If the objects are arranged in sorting order, then we can search for
given object by using binary search method by reducing the number of
comparsions, in this case the complexity of this alg is O(logN).
hashtable:
----------
==> hashtable is a data structure that maps keys to values.
==> each position of the table is called as a slot or bucket or record.
==> hashtable uses hash function to calculate the position of object.
Operations:
-----------
1. insertion
2. deletion
3. display
4. search
Implementation of hashtable
---------------------------
class Hashtable:
def __init__(self,size):
self.size = size
self.L = [-1]*size
def print(self):
print("Hashtable Content: ")
for i in range(self.size):
print(f"{i} ====> {self.L[i]}")
def compute(self,value):
return value%self.size
def add(self,value):
hcode = self.compute(value)
if self.L[hcode]==-1:
self.L[hcode] = value
return True
return False
def delete(self,value):
hcode = self.compute(value)
if self.L[hcode]!=-1 and self.L[hcode]==value:
self.L[hcode] = -1
return True
return False
def search(self,value):
hcode = self.compute(value)
if self.L[hcode]==value:
return True
return False
h = Hashtable(10)
print(h.add(13))
print(h.add(55))
print(h.add(99))
print(h.add(78))
print(h.add(53)) #False
h.print()
print(h.delete(56)) #False
print(h.delete(55)) #True
h.print()
print(h.search(13)) #True
print(h.search(55)) #False
C:\test>py test.py
True
True
True
True
False
Hashtable Content:
0 ====> -1
1 ====> -1
2 ====> -1
3 ====> 13
4 ====> -1
5 ====> 55
6 ====> -1
7 ====> -1
8 ====> 78
9 ====> 99
False
True
Hashtable Content:
0 ====> -1
1 ====> -1
2 ====> -1
3 ====> 13
4 ====> -1
5 ====> -1
6 ====> -1
7 ====> -1
8 ====> 78
9 ====> 99
True
False
C:\test>
Collision:
----------
When a function generates the same index/hash code for two or more
objects, then it is very difficult to store that object into the
hashtable in such cases collision will occur. We have to write a hash
function effificently without collision. practicaally it is impossible.
we have collision resolution methods
1. linear probing
2. quadratic probing
3. seperate chaining
1. linear probing
-----------------
Insert 3, 13, 23, 33, 43, 53, 63 etc
class Hashtable:
def __init__(self,size):
self.size = size
self.L = [-1]*size
def print(self):
print("Hashtable Content: ")
for i in range(self.size):
print(f"{i} ====> {self.L[i]}")
def compute(self,value):
return value%self.size
def add(self,value):
hcode = self.compute(value)
for i in range(self.size):
if self.L[hcode]==-1:
self.L[hcode] = value
return True
hcode = hcode + self.compute1(i)
hcode = hcode % self.size
return False
def delete(self,value):
hcode = self.compute(value)
for i in range(self.size):
if self.L[hcode]==-1 and self.L[hcode]==value:
self.L[hcode] = -1
return True
hcode = hcode + self.compute1(i)
hcode = hcode % self.size
return False
def search(self,value):
hcode = self.compute(value)
for i in range(self.size):
if self.L[hcode]==value:
return True
hcode = hcode + self.compute1(i)
hcode = hcode % self.size
return False
h = Hashtable(10)
print(h.add(3))
print(h.add(13))
print(h.add(23))
print(h.add(33))
print(h.add(43))
print(h.add(53))
print(h.add(63))
h.print()
C:\test>py test.py
True
True
True
True
True
True
False
Hashtable Content:
0 ====> -1
1 ====> 53
2 ====> -1
3 ====> 3
4 ====> 13
5 ====> -1
6 ====> 23
7 ====> -1
8 ====> 43
9 ====> 33
2. quadratic probing
--------------------
class Hashtable:
def __init__(self,size):
self.size = size
self.L = [-1]*size
def print(self):
print("Hashtable Content: ")
for i in range(self.size):
print(f"{i} ====> {self.L[i]}")
def compute(self,value):
return value%self.size
def add(self,value):
hcode = self.compute(value)
for i in range(self.size):
if self.L[hcode]==-1:
self.L[hcode] = value
return True
hcode = hcode + self.compute2(i)
hcode = hcode % self.size
return False
def delete(self,value):
hcode = self.compute(value)
for i in range(self.size):
if self.L[hcode]==-1 and self.L[hcode]==value:
self.L[hcode] = -1
return True
hcode = hcode + self.compute2(i)
hcode = hcode % self.size
return False
def search(self,value):
hcode = self.compute(value)
for i in range(self.size):
if self.L[hcode]==value:
return True
hcode = hcode + self.compute2(i)
hcode = hcode % self.size
return False
h = Hashtable(10)
print(h.add(5))
print(h.add(15))
print(h.add(25))
print(h.add(35))
print(h.add(45))
h.print()
C:\test>py test.py
True
True
True
True
False
Hashtable Content:
0 ====> 25
1 ====> -1
2 ====> -1
3 ====> -1
4 ====> -1
5 ====> 5
6 ====> 15
7 ====> -1
8 ====> -1
9 ====> 35
3. seperate chaining
--------------------
class Hashtable:
class Node:
def __init__(self,value,next=None):
self.value = value
self.next = next
def __init__(self,size):
self.size = size
self.L = [None]*size
def print(self):
print("Hashtable Content: ")
for i in range(self.size):
print(f"{i} ====> ",end=" ")
temp = self.L[i]
while temp!=None:
print(temp.value,end=" => ")
temp = temp.next
print("None")
def compute(self,value):
return value%self.size
def add(self,value):
hcode = self.compute(value)
self.L[hcode] = self.Node(value,self.L[hcode])
def delete(self,value):
hcode = self.compute(value)
temp = self.L[hcode]
if temp!=None and temp.value == value:
self.L[hcode] = temp.next
return True
while temp!=None:
temp1 = temp.next
if temp1!=None and temp1.value == value:
temp.next = temp1.next
return True
temp = temp1
return False
def search(self,value):
hcode = self.compute(value)
temp = self.L[hcode]
while temp!=None:
if temp.value == value:
return True
temp = temp.next
return False
h = Hashtable(10)
h.add(3)
h.add(13)
h.add(23)
h.add(34)
h.add(77)
h.add(29)
h.add(22)
h.add(33)
h.add(43)
h.add(53)
h.print()
print(h.delete(23))
h.print()
print(h.search(13))
print(h.search(23))
C:\test>py test.py
Hashtable Content:
0 ====> None
1 ====> None
2 ====> 22 => None
3 ====> 53 => 43 => 33 => 23 => 13 => 3 => None
4 ====> 34 => None
5 ====> None
6 ====> None
7 ====> 77 => None
8 ====> None
9 ====> 29 => None
True
Hashtable Content:
0 ====> None
1 ====> None
2 ====> 22 => None
3 ====> 53 => 43 => 33 => 13 => 3 => None
4 ====> 34 => None
5 ====> None
6 ====> None
7 ====> 77 => None
8 ====> None
9 ====> 29 => None
True
False
Bit Manipulations:
------------------
Introduction:
-------------
It is used to perform operations on binary numbers, because the decimal
numbers are internally converted into binary form for eval purpose, that
why if you are perform any operations directly on binary numbers
efficiency will be imporved for that we should go for bit manipulations.
Number Systems:
---------------
A digital system can understand the digits by using the following
components
1. digit
2. position of that digit
3. base of that number system
Ex:
n = 13
Quotient Remainder
13/2 6 1
6/2 3 0
3/2 1 1
1/2 0 1
Ans: 1101
Method2:
--------
Find binary equivalent for the given number is 8-4-2-1
Ex:
8 4 2 1
n=13 ---> 1 1 0 1
n=12 ---> 1 1 0 0
n=5 ----> 0 1 0 1
Ex: 1101
1x2^0 = 1x1 = 1
0x2^1 = 0x2 = 0
1x2^2 = 1x4 = 4
1x2^3 = 1x8 = 8
---------------
13
Method2:
--------
By using 8 4 2 1 code we can find decimal number for the given binary
Bitwise operators:
------------------
==> it is a special operators that are existed in all most all PLs
==> it is an efficient way to work with apps
==> it is very fast when compared with other operators
==> it requires linear time for execution
==> easy implement
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0
Applications
------------
1. Even or Odd number
2. Swapping of two numbers
3. Lower case to Upper case conversion
4. Upper case to Lower case conversion
1. Even or Odd number
---------------------
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
n=int(input())
if (n&1)==0:
print("even")
else:
print("odd")
C:\test>py test.py
4
even
C:\test>py test.py
5
odd
C:\test>py test.py
10
30
before: a=10 and b=30
after : a=30 and b=10
C:\test>py test.py
Enter any name in lower case:prakash
PRAKASH
C:\test>py test.py
Enter any name in lower case:prakash
PRAKASH
C:\test>py test.py
Enter any name in upper case:JAVA
java
Dynamic Programming:
--------------------
==> It is same as recursion.
==> Recursion with optimized solution is nothing but DP.
Ex:
---
Fib number program by using recursion.
def fib(n):
global c
c=c+1
if n==0 or n==1:
return n
return fib(n-1)+fib(n-2)
c = 0
n=int(input("Enter nth term: ")) #5
# 0 1 1 2 3 5 8 13 . . .
print(fib(n)) #5
print(c)
C:\test>py test.py
Enter nth term: 5
5
15
1. Memoization (recursion)
2. Tabulation (Arrays/List)
Ex:
---
def fib(n,L):
global c
c=c+1
if n==0 or n==1:
return n
if L[n]!=0:
return L[n]
L[n] = fib(n-1,L) + fib(n-2,L)
return L[n]
c = 0
n=int(input("Enter nth term: ")) #5
# 0 1 1 2 3 5 8 13 . . .
L = [0]*(n+1)
print(fib(n,L)) #5
print(c)
C:\test>py test.py
Enter nth term: 5
5
9
Ex:
---
def fib(n):
L = [0]*(n+1)
L[0] = 0
L[1] = 1
for i in range(2,n+1):
L[i] = L[i-1] + L[i-2]
return L[n]
C:\test>py test.py
Enter nth term: 5
5
heap tree ----> where min/max element will be there as root node.
Ex:
---
from queue import PriorityQueue
q = PriorityQueue()
q.put(4)
q.put(2)
q.put(5)
q.put(1)
q.put(3)
C:\test>py test.py
1
2
3
4
5
Ex:
---
from queue import PriorityQueue
q = PriorityQueue()
q.put((4,'Read'))
q.put((2,'Play'))
q.put((5,'Write'))
q.put((1,'Code'))
q.put((3,'Study'))
C:\test>py test.py
(1, 'Code')
(2, 'Play')
(3, 'Study')
(4, 'Read')
(5, 'Write')
Coins
-----
100-48 = 52
Return 52/-
result = 0
while(items)
{
i = select_item
if item is feasible
then add that item to result
return result
Ex:
---
def fun(coins,amount):
result = 0
coins.sort(reverse=True)
for coin in coins:
if coin<=amount:
x = amount//coin
result = result+x
amount = amount - x*coin
if amount==0:
break
return result
C:\test>py test.py
2