DSA lab program
DSA lab program
AIM:
To Implement simple ADTs as Python classes using Stack,Queue,List using python.
ALGORITHM:
Program:
stack = []
stack.append('a')
stack.append('b')
stack.append('c')
print('Initial stack')
print(stack)
print(stack.pop())
print(stack.pop())
print(stack.pop())
print(stack)
queue = []
queue.append('a')
queue.append('b')
queue.append('c')
print("Initial queue")
print(queue)
print(queue.pop(0))
print(queue.pop(0))
print(queue.pop(0))
print("\nQueue after removing elements")
print(queue)
List = [1,2,3,4]
print(List)
print(List)
OutPut:
Initial stack
[]
Initial queue
[]
Initial List:
[1, 2, 3, 4]
RESULT:
Thus the Implementation of simple ADTs as Python classes was executed successfully
EX.NO:2 RECURSIVE ALGORITHM
AIM:
To Implement a recursive algorithms in Python using Fibonacci Series
ALGORITHM:
Step 1:Input the 'n' value until which the Fibonacci series has to be generated.
No = 6
num1, num2 = 3, 1
count = 0
if No <= 0:
print("Invalid Number")
else:
print(num1)
num1 = num2
num2 = nth
count += 1
Output:
14
RESULT:
AIM:
ALGORITHM:
Program:
class Node:
self.data = data
self.next = None
@staticmethod
def add(data):
return Node(data)
i=0
while i < n:
i += 1
def find_length(head):
cur = head
count = 0
count += 1
cur = cur.next
return count
def convert_array(head):
length = find_length(head)
arr = []
cur = head
arr.append(cur.data)
cur = cur.next
print_array(arr, length)
head = Node(6)
head.next = Node.add(4)
head.next.next = Node.add(3)
head.next.next.next = Node.add(4)
convert_array(head)
OutPut:
6434
RESULT:
AIM:
ALGORITHM:
Step 2:Write function for all the basic operations of list - create(), insert(), deletion(), display().
Step 3:Using append() to extend the elements, removal() to delete the elements
Program:
List = [1, 2, 3, 4]
print("Initial List:")
print(List)
print(List)
print("\nList of numbers:")
print(new_list)
print("\nList Items:")
print(another_list[0])
print(another_list[2])
print("Initial List:")
print(List)
List.insert(3, 12)
List.insert(0, 'Geeks')
print(List)
print("Initial List:")
print(large_list)
large_list.remove(5)
large_list.remove(6)
print(large_list)
large_list.remove(i)
print(large_list)
print("\nMulti-Dimensional List:")
print(multi_dim_list)
Output:
Initial List:
[1, 2, 3, 4]
List of numbers:
List Items:
Geeks
Geeks
Initial List:
[1, 2, 3, 4]
['Geeks', 1, 2, 3, 12, 4]
Initial List:
Multi-Dimensional List:
RESULT:
Thus the list was created, inserted, removed and extend the element was executed successfully.
EX.NO:5 IMPLEMENTATION OF STACK AND QUEUE ADTS
AIM:
ALGORITHM:
Step 2:Write function for all the basic operations of stack - append(), POP()
Program:
stack = []
stack.append('a')
stack.append('b')
stack.append('c')
print('Initial stack')
print(stack)
print(stack.pop())
print(stack.pop())
print(stack.pop())
print(stack)
queue = []
queue.append('a')
queue.append('b')
queue.append('c')
print("Initial queue")
print(queue)
print(queue.pop(0))
print(queue.pop(0))
print(queue.pop(0))
Output:
Initial stack
[]
Initial queue
[]
Result:
AIM:
ALGORITHM:
Step 3: print [poly] statement have the sum of two polynomial elements.
Program:
size = max(m, n)
for i in range(m):
sum_poly[i] = A[i]
for i in range(n):
sum_poly[i] += B[i]
return sum_poly
for i in range(n):
print(poly[i], end="")
if i != 0:
print(f"x^{i}", end="")
# Print the "+" sign between terms, but not after the last term
if i != n - 1:
print() # To ensure we move to the next line after the polynomial is printed
if __name__ == '__main__':
B = [1, 2, 4] # 1 + 2x + 4x^2
m = len(A)
n = len(B)
printPoly(A, m)
printPoly(B, n)
sum_poly = add(A, B, m, n)
size = max(m, n)
printPoly(sum_poly, size)
Output:
1 + 2x^1 + 4x^2
RESULT:
ALGORITHM:
Step 2: check if empty or not ,the stack will insert the elements.
Step 4: Check the operator based on the precedence the expression will be evaluated.
Program:
class Conversion:
self.top = -1
self.capacity = capacity
self.array = []
self.output = []
def isEmpty(self):
def peek(self):
return self.array[-1]
def pop(self):
if not self.isEmpty():
self.top -= 1
return self.array.pop()
else:
self.top += 1
self.array.append(op)
try:
a = self.precedence[i]
b = self.precedence[self.peek()]
except KeyError:
return False
for i in exp:
if self.isOperand(i):
self.output.append(i)
elif i == '(':
self.push(i)
elif i == ')':
a = self.pop()
self.output.append(a)
if not self.isEmpty() and self.peek() != '(':
else:
else:
self.output.append(self.pop())
self.push(i)
self.output.append(self.pop())
print("".join(self.output))
# Example usage
exp = "a+b*(c^d-e)^(f+g*h)-i"
obj = Conversion(len(exp))
obj.infixToPostfix(exp)
Output:
abcd^e-fgh*+^*+i-
RESULT:
AIM:
ALGORITHM:
1. Input the number of processes required to be scheduled using FCFS, burst time for each process
and its arrival time.
2. Calculate the Finish Time, Turn Around Time and Waiting Time for each process which in turn help
to calculate Average Waiting Time and Average Turn Around Time required by CPU to schedule given
set of process using FCFS.
f. for i >= 1, Waiting Time T i = Turn Around Time T i - Burst Time T i - 1 3. Process with less arrival
time comes first and gets scheduled first by the CPU.
4. Calculate the Average Waiting Time and Average Turn Around Time.
Program:
for i in range(n):
total_tat = 0
# Print header
# Print each process's burst time, waiting time, and turnaround time
for i in range(n):
total_wt += wt[i]
total_tat += tat[i]
print(f"{i + 1}\t\t{bt[i]}\t\t{wt[i]}\t\t{tat[i]}")
# Main function
if __name__ == "__main__":
findavgTime(processes, n, burst_time)
Output:
1 10 0 10
2 5 10 15
3 8 15 23
RESULT:
AIM:
ALGORITHM:
Step 1: Start
Program:
list_of_elements = [4, 3, 8, 9, 2, 7]
found = False
for i in range(len(list_of_elements)):
if list_of_elements[i] == x:
found = True
break
if not found:
RESULT:
Thus the python program for the implementation of linear search was executed and the
output was obtained.
Ex.No:7B BINARY SEARCH
AIM:
ALGORITHM:
STEP 1: Start
STEP 6: Repeat step 7 to 12 until first <=last and not to found occur false. STEP 7: Calculate mid =
(first + last)/ / 2
STEP 8: Check if item_list[mid]==item then go to step 9 otherwise go to step 10. STEP 9: Assign
found=True
STEP 10: Check if then < item_list[mid]then go to step 11 otherwise go to step 12. STEP 11: Calculate
last=mid – 1
STEP 13: Repeat found to binary_search() and print the value. STEP 14: Repeat the step 2 to 13 for
binary_search()
Program:
first = 0
last = len(item_list) - 1
found = False
if item_list[mid] == item:
found = True
else:
last = mid - 1
else:
first = mid + 1
return found
Output:
False
True
RESULT:
Thus the python program for the implementation of binary search was executed
AIM:
ALGORITHM:
STEP 1: Start
Program:
def selectionSort(alist):
positionOfMax = 0
positionOfMax = location
# Swap the found maximum element with the last element of the unsorted part
temp = alist[fillslot]
alist[fillslot] = alist[positionOfMax]
alist[positionOfMax] = temp
# List to be sorted
alist = [45, 62, 13, 71, 77, 31, 49, 53, 20]
print(alist)
Output:
RESULT:
Thus the python program for the implementation of selection sort was executed and the
output was obtained.
EX.NO:7D INSERTION SORT
AIM:
ALGORITHM:
STEP 1: Start
STEP 6: Repeat the step 7 to step 8 until position >0 and alist[position1]>current value occur false.
STEP 7: Assign alist[position]=alist[position-1]
Program:
def insertionSort(alist):
currentvalue = alist[index]
position = index
alist[position] = alist[position - 1]
position = position - 1
alist[position] = currentvalue
# List to be sorted
alist = [15, 22, 39, 41, 67, 73, 85, 86, 90]
# Call the insertion sort function
insertionSort(alist)
print(alist)
Output:
RESULT:
Thus the python program for the implementation of insertion sort was executed and output was
obtained
EX.NO:8 IMPLEMENTATION OF HASH TABLES
AIM:
ALGORITHM:
SETP 1:Create a structure, data (hash table item) with key and value as data.
SETP 2.for loops to define the range within the set of elements.
Program:
def checkPrime(n):
if n == 1 or n == 0:
return 0
if n % i == 0:
return 0
return 1
def getPrime(n):
if n % 2 == 0:
n += 1
n += 2
return n
def hashFunction(key):
capacity = getPrime(10)
index = hashFunction(key)
def removeData(key):
index = hashFunction(key)
insertData(123, "apple")
insertData(432, "mango")
insertData(213, "banana")
insertData(654, "guava")
print(hashTable)
removeData(123)
print(hashTable)
Output:
[[], [], [123, 'apple'], [432, 'mango'], [213, 'banana'], [654, 'guava'], [], [], [], []]
[[], [], [], [432, 'mango'], [213, 'banana'], [654, 'guava'], [], [], [], []]
RESULT:
Aim:
Algorithm:
STEP 2: Intially all the left and right vertex are none , then declare the values using insert() function.
Program:
class Node:
# Initialize the node with data and set left and right children to None
self.left = None
self.right = None
self.data = data
if self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
else:
self.data = data
def PrintTree(self):
if self.left:
self.left.PrintTree()
if self.right:
self.right.PrintTree()
# Example usage
root = Node(12)
root.insert(6)
root.insert(14)
root.insert(3)
root.PrintTree() # This will print the elements in the tree in sorted order
Output:
3 6 12 14
Result:
Aim:
Algorithm:
Inorder(tree)
Preorder(tree)
Postorder(tree)
Program:
class Node:
self.left = None
self.right = None
self.val = key
def printInorder(root):
if root:
printInorder(root.left)
printInorder(root.right)
def printPostorder(root):
if root:
printPostorder(root.left)
printPostorder(root.right)
def printPreorder(root):
if root:
printPreorder(root.left)
printPreorder(root.right)
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
printPreorder(root)
printInorder(root)
printPostorder(root)
Output:
12453
42513
45231
Result:
Algorithm:
Step 2 - Compare the search element with the value of root node in the tree.
Step 3 - If both are matched, then display "Given node is found!!!" and terminate the function
Step 4 - If both are not matched, then check whether search element is smaller or larger than that
node value.
Step 5 - If search element is smaller, then continue the search process in left subtree.
Step 6- If search element is larger, then continue the search process in right subtree.
Step 7 - Repeat the same until we find the exact element or until the search element is compared
with the leaf node
Step 8 - If we reach to the node having the value equal to the search value then display "Element is
found" and terminate the function.
Program:
class Node:
self.left = None
self.right = None
self.data = data
if self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
else:
self.data = data
if self.left is None:
return self.left.findval(lkpval)
if self.right is None:
return self.right.findval(lkpval)
else:
def PrintTree(self):
if self.left:
self.left.PrintTree()
if self.right:
self.right.PrintTree()
# Example usage
root = Node(12)
root.insert(6)
root.insert(14)
root.insert(3)
print(root.findval(7))
Output:
7 Not Found
13 Not Found
Result:
Thus the Implementation of Binary Search Trees using python was executed successfully.
Ex.NO:11 Implementation of Heaps
Aim:
Algorithm:
Program:
import heapq
heapq.heapify(H)
heapq.heappush(H, 8)
heapq.heappop(H)
Result:
Aim:
Algorithm:
Step 1: Create a dictionary where each key represents a vertex and its value is a list of adjacent
vertices.
Step 2: Instantiate the Graph class by passing the graph dictionary to its constructor.
Step 3: Call the getVertices method on the graph object to get a list of all vertices.
Step 4: Call the edges method on the graph object to get a list of all edges.
Step 5: Print the list of vertices and edges obtained from Steps 3 and 4.
Step 6: Conclude the algorithm after displaying the vertices and edges. Optionally, extend the
functionality for further graph operations.
Program:
class Graph:
if gdict is None:
gdict = {}
self.gdict = gdict
def getVertices(self):
return list(self.gdict.keys())
def edges(self):
return self.findedges()
def findedges(self):
edgename = []
edgename.append({vrtx, nxtvrtx})
return edgename
graph_elements = {
"d": ["e"],
"e": ["d"]
g = Graph(graph_elements)
print("Vertices:", g.getVertices())
print("Edges:", g.edges())
Output:
Edges: [{'b', 'a'}, {'c', 'a'}, {'d', 'b'}, {'d', 'c'}, {'e', 'd'}]
Result:
Aim:
Algorithm:
DFS:
Step 2 - Select any vertex as starting point for traversal. Visit that vertex and push it on to the Stack.
Step 3 - Visit any one of the non-visited adjacent vertices of a vertex which is at the top of stack and
push it on to the stack.
Step 4 - Repeat step 3 until there is no new vertex to be visited from the vertex which is at the top of
the stack.
Step 5 - When there is no new vertex to visit then use back tracking and pop one vertex from the
stack.
Step 7 - When stack becomes Empty, then produce final spanning tree by removing unused edges
from the graph
BFS:
Step 2 - Select any vertex as starting point for traversal. Visit that vertex and insert it into the Queue.
Step 3 - Visit all the non-visited adjacent vertices of the vertex which is at front of the Queue and
insert them into the Queue.
Step 4 - When there is no new vertex to be visited from the vertex which is at front of the Queue
then delete that vertex.
Step 6 - When queue becomes empty, then produce final spanning tree by removing unused edges
from the graph
program:
BFS:
import collections
visited.add(root)
while queue:
if __name__ == '__main__':
bfs(graph, 0)
Output:
0123
DFS:
Program:
import sys
def ret_graph():
return {
while stack:
print("FOUND:", curr)
print(path)
return
print("Not found")
print(path)
# Graph initialization
graph = ret_graph()
start = 'A'
dest = 'J'
print("DFS Traversal:")
Output:
DFS Traversal:
FOUND: J
Result:
Aim: To Implement single source shortest path algorithm using Bellman Ford Algorithm
Algorithm:
Step 1: This step initializes distances from source to all vertices as infinite and distance to source
itself as 0. Create an array dist[] of size |V| with all values as infinite except dist[src] where src is
source vertex.
Step 2: This step calculates shortest distances. Do following |V|-1 times where |V| is the number of
vertices in given graph. a) Do following for each edge u-v If dist[v] > dist[u] + weight of edge uv, then
update dist[v] dist[v] = dist[u] + weight of edge uv
Step 3: This step reports if there is a negative weight cycle in graph. Do following for each edge u-v If
dist[v] > dist[u] + weight of edge uv, then “Graph contains negative weight cycle” The idea of step 3
is, step 2 guarantees shortest distances if graph doesn’t contain negative weight cycle. If we iterate
through all edges one more time and get a shorter path for any vertex, then there is a negative
weight cycle
Program:
dis = [maxsize] * V
dis[src] = 0
for j in range(E):
for i in range(E):
x = graph[i][0]
y = graph[i][1]
weight = graph[i][2]
return
for i in range(V):
if __name__ == "__main__":
graph = [
[0, 1, -1],
[0, 2, 4],
[1, 2, 3],
[1, 3, 2],
[1, 4, 2],
[3, 2, 5],
[3, 1, 1],
[4, 3, -3]
BellmanFord(graph, V, E, 0)
Output:
0 0
1 -1
2 2
3 -2
4 1
Result:
Thus the Implementation of single source shortest path algorithm was successfully executed.
Ex.No:14 Implementation of minimum spanning tree algorithms
Aim: To implement the minimum spanning tree algorithms using Kruskal Algorithm
Algorithm:
Step 3: Start with the smallest weighted and beginning growing the minimum weighted spanning
tree from this edge.
Step 4: Add the next available edge that does not form a cycle to the construction of the minimum
weighted spanning tree. If the addition of the next least weighted edge forms a cycle, do not use it.
Step 5: Continue with step 4 until you have a spanning tree.
program:
class Graph:
self.graph.append([u, v, w])
if parent[i] == i:
return i
else:
xroot = self.find(parent, x)
yroot = self.find(parent, y)
if rank[xroot] < rank[yroot]:
parent[xroot] = yroot
parent[yroot] = xroot
else:
parent[yroot] = xroot
rank[xroot] += 1
def kruskal_algo(self):
parent = []
rank = []
parent.append(node)
rank.append(0)
u, v, w = self.graph[i]
i=i+1
x = self.find(parent, u)
y = self.find(parent, v)
# If including this edge does not cause a cycle
if x != y:
e=e+1
result.append([u, v, w])
self.apply_union(parent, rank, x, y)
# Example usage
g = Graph(6)
g.add_edge(0, 1, 4)
g.add_edge(0, 2, 4)
g.add_edge(1, 2, 2)
g.add_edge(2, 3, 3)
g.add_edge(2, 5, 2)
g.add_edge(2, 4, 4)
g.add_edge(3, 4, 3)
g.add_edge(5, 4, 3)
g.kruskal_algo()
output:
1 - 2: 2
2 - 5: 2
2 - 3: 3
3 - 4: 3
0 - 1: 4
Result: