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

DSA lab program

The document outlines various exercises related to implementing Abstract Data Types (ADTs) in Python, including stacks, queues, lists, and recursive algorithms. Each exercise provides an aim, algorithm, program code, and output results demonstrating successful execution. Key applications include polynomial addition, infix to postfix conversion using stacks, and First-Come-First-Serve (FCFS) CPU scheduling using queues.

Uploaded by

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

DSA lab program

The document outlines various exercises related to implementing Abstract Data Types (ADTs) in Python, including stacks, queues, lists, and recursive algorithms. Each exercise provides an aim, algorithm, program code, and output results demonstrating successful execution. Key applications include polynomial addition, infix to postfix conversion using stacks, and First-Come-First-Serve (FCFS) CPU scheduling using queues.

Uploaded by

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

Ex.

No:1 IMPLEMENT SIMPLE ADTS AS PYTHON CLASSES

AIM:
To Implement simple ADTs as Python classes using Stack,Queue,List using python.

ALGORITHM:

Step 1: Create a Stack[ ],Queue[],List[] with MAX size as your wish.


Step 2: Write function for all the basic operations of stack,Queue,List - PUSH(), POP() and
DISPLAY(),append(),Extend().
Step 3: Close the program

Program:

stack = []

stack.append('a')

stack.append('b')

stack.append('c')

print('Initial stack')

print(stack)

print('\nElements poped from stack:')

print(stack.pop())

print(stack.pop())

print(stack.pop())

print('\nStack after elements are poped:')

print(stack)

queue = []

queue.append('a')

queue.append('b')

queue.append('c')

print("Initial queue")

print(queue)

print("\nElements dequeued from 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("Initial List: ")

print(List)

List.extend([8, 'Geeks', 'Always'])

print("\nList after performing Extend Operation: ")

print(List)

OutPut:

Initial stack

['a', 'b', 'c']

Elements poped from stack:

Stack after elements are poped:

[]

Initial queue

['a', 'b', 'c']

Elements dequeued from queue

Queue after removing elements

[]

Initial List:

[1, 2, 3, 4]

List after performing Extend Operation:

[1, 2, 3, 4, 8, 'Geeks', 'Always']

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.

Step 2:Initialize sum = 0, a = 0, b = 1 and count = 1

Step 3:while (count <= n)

Step 4:print sum

Step 5:Increment the count variable

Step 6:swap a and b


Step 7:sum = a + b
Step 8:while (count > n)
Step 9:End the algorithm
Step 10:Else
Step 11:Repeat from steps 4 to 7
Program:

No = 6

num1, num2 = 3, 1

count = 0

if No <= 0:

print("Invalid Number")

else:

print("Fibonacci sequence for limit of ", No, ":")

while count < No:

print(num1)

nth = num1 + num2

num1 = num2

num2 = nth

count += 1

Output:

Fibonacci sequence for limit of 6 :

14

RESULT:

Thus the Implementation of recursive algorithms in Python using Fibonacci


series was executed successfully.
EX.NO:3 LIST ADT USING PYTHON ARRAYS

AIM:

To Implement List ADT using Python arrays

ALGORITHM:

Step 1: Using define function intialise the list


Step 2: while loop to declare the elements until the condition is satisfied.
Step 3: Using convert arr function to convert the elemnts to an array
Step 4: Stop the program

Program:

class Node:

def __init__(self, data):

self.data = data

self.next = None

@staticmethod

def add(data):

return Node(data)

def print_array(a, n):

i=0

while i < n:

print(a[i], end=" ")

i += 1

def find_length(head):

cur = head

count = 0

while cur is not None:

count += 1

cur = cur.next
return count

def convert_array(head):

length = find_length(head)

arr = []

cur = head

while cur is not None:

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:

Thus the implementation of List in arrays was executed successfully.


Ex.NO:4 LINKED LIST IMPLEMENTATIONS OF LIST

AIM:

To Implement the Linked list implementations of List using python

ALGORITHM:

Step 1:Create a list[ ] with MAX size as your wish.

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

Step 4:Close the program

Program:

# Initialize the list

List = [1, 2, 3, 4]

print("Initial List:")

print(List)

# Extend the list

List.extend([8, 'Geeks', 'Always'])

print("\nList after performing Extend Operation:")

print(List)

# Create a new list

new_list = [10, 20, 14]

print("\nList of numbers:")

print(new_list)

# Create another list

another_list = ["Geeks", "For", "Geeks"]

print("\nList Items:")

print(another_list[0])

print(another_list[2])

# Initialize a new list


List = [1, 2, 3, 4]

print("Initial List:")

print(List)

# Insert elements into the list

List.insert(3, 12)

List.insert(0, 'Geeks')

print("\nList after performing Insert Operation:")

print(List)

# Create a new list

large_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

print("Initial List:")

print(large_list)

# Remove elements from the list

large_list.remove(5)

large_list.remove(6)

print("\nList after Removal of two elements:")

print(large_list)

# Remove a range of elements from the list

for i in range(1, 5):

large_list.remove(i)

print("\nList after Removing a range of elements:")

print(large_list)

# Create a multi-dimensional list

multi_dim_list = [['Geeks', 'For'], ['Geeks']]

print("\nMulti-Dimensional List:")

print(multi_dim_list)
Output:

Initial List:

[1, 2, 3, 4]

List after performing Extend Operation:

[1, 2, 3, 4, 8, 'Geeks', 'Always']

List of numbers:

[10, 20, 14]

List Items:

Geeks

Geeks

Initial List:

[1, 2, 3, 4]

List after performing Insert Operation:

['Geeks', 1, 2, 3, 12, 4]

Initial List:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

List after Removal of two elements:

[1, 2, 3, 4, 7, 8, 9, 10, 11, 12]

List after Removing a range of elements:

[7, 8, 9, 10, 11, 12]

Multi-Dimensional List:

[['Geeks', 'For'], ['Geeks']]

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:

To Implement of Stack and Queue ADTs in python.

ALGORITHM:

Step 1: Create a Stack[ ],Queue[] with MAX size as your wish.

Step 2:Write function for all the basic operations of stack - append(), POP()

Step 3: Close the program

Program:

stack = []

stack.append('a')

stack.append('b')

stack.append('c')

print('Initial stack')

print(stack)

print('\nElements poped from stack:')

print(stack.pop())

print(stack.pop())

print(stack.pop())

print('\nStack after elements are poped:')

print(stack)

queue = []

queue.append('a')

queue.append('b')

queue.append('c')

print("Initial queue")

print(queue)

print("\nElements dequeued from queue")

print(queue.pop(0))

print(queue.pop(0))

print(queue.pop(0))

print("\nQueue after removing elements")


print(queue)

Output:

Initial stack

['a', 'b', 'c']

Elements poped from stack:

Stack after elements are poped:

[]

Initial queue

['a', 'b', 'c']

Elements dequeued from queue

Queue after removing elements

[]

Result:

Thus the program was executed successfully


EX.NO: 6A ) APPLICATION OF LIST

AIM:

To implement list application using Polynomial Addition in python.

ALGORITHM:

Step 1: Using the define function initial elements will be declared.

Step 2: for loop gives the output of sum of the elements

Step 3: print [poly] statement have the sum of two polynomial elements.

Step 4: Close the program.

Program:

def add(A, B, m, n):

# Find the size of the result array (max of m and n)

size = max(m, n)

# Initialize the result polynomial with zeros

sum_poly = [0] * size

# Add corresponding coefficients of A and B

for i in range(m):

sum_poly[i] = A[i]

for i in range(n):

sum_poly[i] += B[i]

return sum_poly

def printPoly(poly, n):

# Print the polynomial in human-readable form

for i in range(n):

# Print the coefficient

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(" + ", end="")

print() # To ensure we move to the next line after the polynomial is printed

if __name__ == '__main__':

# Define two polynomials as lists of coefficients

A = [5, 0, 10, 6] # 5 + 0x + 10x^2 + 6x^3

B = [1, 2, 4] # 1 + 2x + 4x^2

# Lengths of polynomials A and B

m = len(A)

n = len(B)

# Print first polynomial

print("First polynomial is:")

printPoly(A, m)

# Print second polynomial

print("Second polynomial is:")

printPoly(B, n)

# Compute the sum of the two polynomials

sum_poly = add(A, B, m, n)

# The size of the result polynomial is the max length of A and B

size = max(m, n)

# Print the sum polynomial


print("Sum polynomial is:")

printPoly(sum_poly, size)

Output:

First polynomial is:

5 + 0x^1 + 10x^2 + 6x^3

Second polynomial is:

1 + 2x^1 + 4x^2

Sum polynomial is:

6 + 2x^1 + 14x^2 + 6x^3

RESULT:

Thus the program was executed successfully.


EX.NO:6B APPLICATION OF STACK

AIM: To implement the conversion of infix to postfix in stack.

ALGORITHM:

Step 1: Read the given expression

Step 2: check if empty or not ,the stack will insert the elements.

Step 3: Using push(),pop() to insert the element or remove the element.

Step 4: Check the operator based on the precedence the expression will be evaluated.

Step 5: Close the program

Program:

class Conversion:

def __init__(self, capacity):

self.top = -1

self.capacity = capacity

self.array = []

self.output = []

self.precedence = {'+': 1, '-': 1, '*': 2, '/': 2, '^': 3}

def isEmpty(self):

return True if self.top == -1 else False

def peek(self):

return self.array[-1]

def pop(self):

if not self.isEmpty():

self.top -= 1

return self.array.pop()

else:

return "$" # Return some sentinel value if the stack is empty


def push(self, op):

self.top += 1

self.array.append(op)

def isOperand(self, ch):

return ch.isalpha() # Operand is an alphabet (a-z or A-Z)

def notGreater(self, i):

try:

a = self.precedence[i]

b = self.precedence[self.peek()]

return True if a <= b else False

except KeyError:

return False

def infixToPostfix(self, exp):

# Iterate over the expression

for i in exp:

# If the character is an operand, append it to the output list

if self.isOperand(i):

self.output.append(i)

# If it's '(', push it to the stack

elif i == '(':

self.push(i)

# If it's ')', pop until '('

elif i == ')':

while not self.isEmpty() and self.peek() != '(':

a = self.pop()

self.output.append(a)
if not self.isEmpty() and self.peek() != '(':

return -1 # Invalid expression (unmatched parentheses)

else:

self.pop() # Pop '('

# If it's an operator, handle precedence

else:

while not self.isEmpty() and self.notGreater(i):

self.output.append(self.pop())

self.push(i)

# Pop all remaining operators from the stack

while not self.isEmpty():

self.output.append(self.pop())

# Print the resulting postfix expression

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:

Thus the conversion can be successfully executed


Ex.No:6c APPLICATION OF QUEUE

AIM:

To implement the application of queue using FCFS CPU Scheduling.

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.

a. for i = 0, Finish Time T 0 = Arrival Time T 0 + Burst Time T 0

b. for i >= 1, Finish Time T i = Burst Time T i + Finish Time T i - 1

c. for i = 0, Turn Around Time T 0 = Finish Time T 0 - Arrival Time T 0

d. for i >= 1, Turn Around Time T i = Finish Time T i - Arrival Time T i

e. for i = 0, Waiting Time T 0 = Turn Around Time T 0 - Burst Time T 0

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.

5. Stop the program

Program:

def findWaitingTime(processes, n, bt, wt):

wt[0] = 0 # First process has no waiting time

for i in range(1, n):

wt[i] = bt[i - 1] + wt[i - 1]

def findTurnAroundTime(processes, n, bt, wt, tat):

# Calculating turnaround time by adding bt[i] + wt[i]

for i in range(n):

tat[i] = bt[i] + wt[i]

def findavgTime(processes, n, bt):

wt = [0] * n # Initialize waiting time array

tat = [0] * n # Initialize turnaround time array


total_wt = 0

total_tat = 0

# Calculate waiting time and turnaround time

findWaitingTime(processes, n, bt, wt)

findTurnAroundTime(processes, n, bt, wt, tat)

# Print header

print("Processes Burst time Waiting time Turnaround time")

# 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]}")

# Calculate and print average waiting time and turnaround time

print(f"Average waiting time = {total_wt / n}")

print(f"Average turnaround time = {total_tat / n}")

# Main function

if __name__ == "__main__":

processes = [1, 2, 3] # Process IDs (this can be ignored in calculation)

n = len(processes) # Number of processes

burst_time = [10, 5, 8] # Burst times for each process

findavgTime(processes, n, burst_time)
Output:

Processes Burst time Waiting time Turnaround time

1 10 0 10

2 5 10 15

3 8 15 23

Average waiting time = 8.333333333333334

Average turnaround time = 16.0

RESULT:

Thus the FCFS CPU Scheduling was Executed Successfully


EX.NO:7A LINEAR SEARCH

AIM:

To implement the linear search program using python.

ALGORITHM:

Step 1: Start

Step 2: Call Sequential _Search() with list of arguments.

Step 3: Assign pos=0

Step 4: Assign found=False

Step 5: Repeat step 5 to 7 until pos

Program:

# List of elements to search in

list_of_elements = [4, 3, 8, 9, 2, 7]

# Input from user

x = int(input("Enter number to search: "))

# Flag to track if the element is found

found = False

# Iterate through the list to search for the element

for i in range(len(list_of_elements)):

if list_of_elements[i] == x:

found = True

print("%d found at %dth position" % (x, i))

break

# If the element is not found, print a message

if not found:

print("%d is not in the list" % x)


Output:

Enter number to search: 4

4 found at 0th position

Enter number to search: 11

11 is not in the list

RESULT:

Thus the python program for the implementation of linear search was executed and the
output was obtained.
Ex.No:7B BINARY SEARCH

AIM:

To implement the binary search program using python.

ALGORITHM:

STEP 1: Start

STEP 2: Call binary_search() with list of arguments. STEP 3: Assign first=0.

STEP 4: Calculate last = len(item_list)-1 STEP 5: Assign found =False

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 12: Calculate first=mid + 1

STEP 13: Repeat found to binary_search() and print the value. STEP 14: Repeat the step 2 to 13 for
binary_search()

STEP 15: Repeat the step 2 to 13 for binary_search()

STEP 16: Stop.

Program:

def binary_search(item_list, item):

first = 0

last = len(item_list) - 1

found = False

while first <= last and not found:

mid = (first + last) // 2

if item_list[mid] == item:

found = True

else:

if item < item_list[mid]:

last = mid - 1
else:

first = mid + 1

return found

# Testing the binary_search function

print(binary_search([1, 82, 3, 5, 8], 9)) # This will return False

print(binary_search([1, 2, 3, 5, 8], 5)) # This will return True

Output:

False

True

RESULT:

Thus the python program for the implementation of binary search was executed

and output was obtained.


EX.NO:7C SELECTION SORT

AIM:

To sort the list of elements using selection sort.

ALGORITHM:

STEP 1: Start

STEP 2: Call selection sort() with list of arguments.

STEP 3: Repeat step 4 to step 5 until range occur false.

STEP 4: Check nlist[location]>nlist[maxpos] then go to step 5 otherwise go to step 6.

STEP 5: Assign maxpos = location

STEP 6: Assign temp = nlist[fillslot]

STEP 7: Assign nlist[fillslot]=nlist[maxpos]

STEP 8: Assign nlist[maxpos]=temp

STEP 9: Return and print the sorted numbers.

Program:

def selectionSort(alist):

for fillslot in range(len(alist) - 1, 0, -1):

positionOfMax = 0

for location in range(1, fillslot + 1):

if alist[location] > alist[positionOfMax]:

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]

# Call the selection sort function


selectionSort(alist)

# Print the sorted list

print(alist)

Output:

[13, 20, 31, 45, 49, 53, 62, 71, 77]

RESULT:

Thus the python program for the implementation of selection sort was executed and the
output was obtained.
EX.NO:7D INSERTION SORT

AIM:

To sort list of elements using Insertion sort

ALGORITHM:

STEP 1: Start

STEP 2: Call insertion Sort() with list of arguments.

STEP 3: Repeat the step 4 to step 8 until range occur false

STEP 4: Assign current value = alist[index]

STEP 5:Assign position = index

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]

STEP 8: Calculate position = position – 1.

STEP 9: Assign alist[position]=current value

STEP 10: Print the sorted values.

Program:

def insertionSort(alist):

for index in range(1, len(alist)):

currentvalue = alist[index]

position = index

while position > 0 and alist[position - 1] > currentvalue:

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 the sorted list

print(alist)

Output:

[15, 22, 39, 41, 67, 73, 85, 86, 90]

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:

To Implement the Hash tables using python

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.

SETP 3.hashfunction(key) for the size of capacity

SETP 4.Using insert(),removal() data to be presented or removed.

SETP 5. Stop the program

Program:

# Initialize the hash table with empty lists

hashTable = [[] for _ in range(10)]

def checkPrime(n):

if n == 1 or n == 0:

return 0

for i in range(2, n // 2 + 1): # Updated the range to include n//2

if n % i == 0:

return 0

return 1

def getPrime(n):

if n % 2 == 0:

n += 1

while not checkPrime(n):

n += 2

return n

def hashFunction(key):

capacity = getPrime(10)

return key % capacity


def insertData(key, data):

index = hashFunction(key)

hashTable[index] = [key, data]

def removeData(key):

index = hashFunction(key)

hashTable[index] = [] # Changed to empty list instead of 0

# Inserting data into the hash table

insertData(123, "apple")

insertData(432, "mango")

insertData(213, "banana")

insertData(654, "guava")

# Print the hash table

print(hashTable)

# Removing data from the hash table

removeData(123)

# Print the hash table after removal

print(hashTable)

Output:

[[], [], [123, 'apple'], [432, 'mango'], [213, 'banana'], [654, 'guava'], [], [], [], []]

[[], [], [], [432, 'mango'], [213, 'banana'], [654, 'guava'], [], [], [], []]

RESULT:

Thus the Implementation of hashing was executed successfully


Ex.No:9a Tree representation

Aim:

To implement tree representation in binary tree format

Algorithm:

STEP 1: Create a binary tree.

STEP 2: Intially all the left and right vertex are none , then declare the values using insert() function.

STEP 3: If data>right element place the element in right

STEP 4: If data<left element place the element in left

STEP 5:prin the tree

STEP 6: Stop the program

Program:

class Node:

def __init__(self, data):

# Initialize the node with data and set left and right children to None

self.left = None

self.right = None

self.data = data

def insert(self, data):

# Insert data into the tree

if self.data:

if data < self.data:

if self.left is None:

self.left = Node(data)

else:

self.left.insert(data)

elif data > self.data:

if self.right is None:

self.right = Node(data)

else:

self.right.insert(data)
else:

self.data = data

def PrintTree(self):

# Print the tree in order (Left, Root, Right)

if self.left:

self.left.PrintTree()

print(self.data, end=' ') # Fixed the print statement

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:

Thus the binary tree was successfully created


Ex.No:9b Tree Traversal Algorithms

Aim:

To Implement traversal using Inorder,Preorder,Postorder techniques.

Algorithm:

Inorder(tree)

1. Traverse the left subtree, i.e., call Inorder(left-subtree)

2. Visit the root.

3. Traverse the right subtree, i.e., call Inorder(right-subtree)

Preorder(tree)

1. Visit the root.

2. Traverse the left subtree, i.e., call Preorder(left-subtree)

3. Traverse the right subtree, i.e., call Preorder(right-subtree)

Postorder(tree)

1. Traverse the left subtree, i.e., call Postorder(left-subtree)

2. Traverse the right subtree, i.e., call Postorder(right-subtree)

3. Visit the root.

Program:

class Node:

def __init__(self, key):

self.left = None

self.right = None

self.val = key

def printInorder(root):

if root:

printInorder(root.left)

print(root.val, end=' ') # Print with space between values

printInorder(root.right)

def printPostorder(root):
if root:

printPostorder(root.left)

printPostorder(root.right)

print(root.val, end=' ') # Print with space between values

def printPreorder(root):

if root:

print(root.val, end=' ') # Print with space between values

printPreorder(root.left)

printPreorder(root.right)

# Creating the binary tree

root = Node(1)

root.left = Node(2)

root.right = Node(3)

root.left.left = Node(4)

root.left.right = Node(5)

# Printing tree traversals

print("\nPreorder traversal of binary tree is")

printPreorder(root)

print("\nInorder traversal of binary tree is")

printInorder(root)

print("\nPostorder traversal of binary tree is")

printPostorder(root)
Output:

Preorder traversal of binary tree is

12453

Inorder traversal of binary tree is

42513

Postorder traversal of binary tree is

45231

Result:

Thus the Implementation of traversal using Inorder,Preorder,Postorder techniques was executed


successfully.
Ex.No:10 Implementation of Binary Search Trees

Aim: To Implement the Binary Search Trees using python

Algorithm:

Step 1-Read the search element from the user.

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:

def __init__(self, data):

self.left = None

self.right = None

self.data = data

def insert(self, data):

if self.data:

if data < self.data:

if self.left is None:

self.left = Node(data)

else:

self.left.insert(data)

elif data > self.data:

if self.right is None:

self.right = Node(data)

else:
self.right.insert(data)

else:

self.data = data

def findval(self, lkpval):

if lkpval < self.data:

if self.left is None:

return str(lkpval) + " Not Found"

return self.left.findval(lkpval)

elif lkpval > self.data:

if self.right is None:

return str(lkpval) + " Not Found"

return self.right.findval(lkpval)

else:

print(str(self.data) + ' is found')

def PrintTree(self):

if self.left:

self.left.PrintTree()

print(self.data, end=' ')

if self.right:

self.right.PrintTree()

# Example usage

root = Node(12)

root.insert(6)

root.insert(14)

root.insert(3)

# Searching for a value

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:

To Implement the Heap algorithm using python

Algorithm:

STEP1:Insert the heap function in the list

STEP 2:using heappush(),heappop(),heapify() to insert ,delete,display the elements.

STEP3:Stop the program

Program:

import heapq

# Initial list of elements

H = [21, 1, 45, 78, 3, 5]

# Convert the list into a heap

heapq.heapify(H)

print(H) # Output the heapified list

# Push a new element (8) into the heap

heapq.heappush(H, 8)

print(H) # Output the heap after pushing 8

# Pop the smallest element from the heap

heapq.heappop(H)

print(H) # Output the heap after popping the smallest element


Output:

[1, 3, 5, 78, 21, 45]

[1, 3, 5, 78, 21, 45, 8]

[3, 8, 5, 78, 21, 45]

Result:

Thus the Implementation of the Heap algorithm was executed succeefully.


Ex.No:12a Graph representation

Aim:

To implement the graph representation using python

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:

def __init__(self, gdict=None):

# Initialize graph with a dictionary of vertices and their edges

if gdict is None:

gdict = {}

self.gdict = gdict

def getVertices(self):

# Return the list of vertices (keys of the dictionary)

return list(self.gdict.keys())

def edges(self):

# Return the edges of the graph using the findedges method

return self.findedges()

def findedges(self):

# Find all the edges in the graph

edgename = []

for vrtx in self.gdict:


for nxtvrtx in self.gdict[vrtx]:

# Ensure the edge is not repeated by adding unordered pairs

if {nxtvrtx, vrtx} not in edgename:

edgename.append({vrtx, nxtvrtx})

return edgename

# Graph definition (corrected with no duplicate key "e")

graph_elements = {

"a": ["b", "c"],

"b": ["a", "d"],

"c": ["a", "d"],

"d": ["e"],

"e": ["d"]

# Create the graph object

g = Graph(graph_elements)

# Print the vertices and edges

print("Vertices:", g.getVertices())

print("Edges:", g.edges())

Output:

Vertices: ['a', 'b', 'c', 'd', 'e']

Edges: [{'b', 'a'}, {'c', 'a'}, {'d', 'b'}, {'d', 'c'}, {'e', 'd'}]

Result:

Thus the implementation of graphs was executed successfully.


Ex.No:12b Graph Traversal Algorithms

Aim:

To Implement using BFS,DFS can be traversed.

Algorithm:

DFS:

Step 1 - Define a Stack of size total number of vertices in the graph.

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 6 - Repeat steps 3, 4 and 5 until stack becomes Empty.

Step 7 - When stack becomes Empty, then produce final spanning tree by removing unused edges
from the graph

BFS:

Step 1 - Define a Queue of size total number of vertices in the graph.

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 5 - Repeat steps 3 and 4 until queue becomes empty.

Step 6 - When queue becomes empty, then produce final spanning tree by removing unused edges
from the graph

program:

BFS:

import collections

def bfs(graph, root):

visited, queue = set(), collections.deque([root])

visited.add(root)
while queue:

vertex = queue.popleft() # Dequeue a vertex from the queue

print(str(vertex) + " ", end="") # Print the vertex

for neighbour in graph[vertex]: # Explore all neighbors

if neighbour not in visited:

visited.add(neighbour) # Mark neighbor as visited

queue.append(neighbour) # Enqueue the neighbor

# Ensure the script is run directly

if __name__ == '__main__':

# Define the graph as an adjacency list

graph = {0: [1, 2], 1: [2], 2: [3], 3: [1, 2]}

# Start the breadth-first traversal from vertex 0

print("Following is Breadth First Traversal: ")

bfs(graph, 0)

Output:

Following is Breadth First Traversal:

0123
DFS:

Program:

import sys

# Function to return the graph as a dictionary

def ret_graph():

return {

'A': {'B': 5.5, 'C': 2, 'D': 6},

'B': {'A': 5.5, 'E': 3},

'C': {'A': 2, 'F': 2.5},

'D': {'A': 6, 'F': 1.5},

'E': {'B': 3, 'J': 7},

'F': {'C': 2.5, 'D': 1.5, 'K': 1.5, 'G': 3.5},

'G': {'F': 3.5, 'I': 4},

'H': {'J': 2},

'I': {'G': 4, 'J': 4},

'J': {'H': 2, 'I': 4},

'K': {'F': 1.5}

# Depth-First Search function

def dfs(graph, start, dest):

stack = [] # Stack for DFS

visited = [] # List to keep track of visited nodes

path = [] # List to store the path

stack.append(start) # Push the start node onto the stack

visited.append(start) # Mark the start node as visited

while stack:

curr = stack.pop() # Pop a node from the stack


path.append(curr) # Add the current node to the path

if curr == dest: # If we found the destination

print("FOUND:", curr)

print(path)

return

# Explore neighbors of the current node

for neigh in graph[curr]:

if neigh not in visited: # If the neighbor is not visited

visited.append(neigh) # Mark it as visited

stack.append(neigh) # Push the neighbor onto the stack

# If the destination is not found

print("Not found")

print(path)

# Graph initialization

graph = ret_graph()

# Starting and destination nodes

start = 'A'

dest = 'J'

# Perform DFS traversal

print("DFS Traversal:")

dfs(graph, start, dest)

Output:

DFS Traversal:

FOUND: J

['A', 'D', 'F', 'G', 'I', 'J']

Result:

Thus the implementation of using BFS,DFS graph can be traversed


Ex.No:13 Implementation of single source shortest path algorithm

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:

from sys import maxsize

def BellmanFord(graph, V, E, src):

# Initialize distances from the source to all vertices as infinite

dis = [maxsize] * V

dis[src] = 0

# Relax all edges |V| - 1 times

for i in range(V - 1):

for j in range(E):

if dis[graph[j][0]] != maxsize and dis[graph[j][0]] + graph[j][2] < dis[graph[j][1]]:

dis[graph[j][1]] = dis[graph[j][0]] + graph[j][2]

# Check for negative-weight cycles

for i in range(E):

x = graph[i][0]

y = graph[i][1]

weight = graph[i][2]

if dis[x] != maxsize and dis[x] + weight < dis[y]:


print("Graph contains negative weight cycle")

return

# Print the distance from the source to each vertex

print("Vertex Distance from Source")

for i in range(V):

print("%d\t\t %d" % (i, dis[i]))

if __name__ == "__main__":

V = 5 # Number of vertices in graph

E = 8 # Number of edges in graph

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:

Vertex Distance from Source

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 1:Label each vertex

Step 2: List the edges in non-decreasing order of weight.

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:

def __init__(self, vertices):

self.V = vertices # Number of vertices

self.graph = [] # List to store the graph edges

def add_edge(self, u, v, w):

"""Add an edge to the graph."""

self.graph.append([u, v, w])

def find(self, parent, i):

"""Find the parent of a node with path compression."""

if parent[i] == i:

return i

else:

return self.find(parent, parent[i])

def apply_union(self, parent, rank, x, y):

"""Union of two subsets."""

xroot = self.find(parent, x)

yroot = self.find(parent, y)
if rank[xroot] < rank[yroot]:

parent[xroot] = yroot

elif rank[xroot] > rank[yroot]:

parent[yroot] = xroot

else:

parent[yroot] = xroot

rank[xroot] += 1

def kruskal_algo(self):

"""Kruskal's algorithm to find the Minimum Spanning Tree."""

result = [] # Store the resultant MST

i, e = 0, 0 # Initial index and count of edges in MST

# Sort the graph edges by weight

self.graph = sorted(self.graph, key=lambda item: item[2])

parent = []

rank = []

# Create V subsets with single elements

for node in range(self.V):

parent.append(node)

rank.append(0)

# Number of edges to be taken is equal to V-1

while e < self.V - 1:

# Step 2: Pick the smallest edge

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)

# Print the resultant MST

for u, v, weight in result:

print("%d - %d: %d" % (u, v, weight))

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

# Execute Kruskal's algorithm

g.kruskal_algo()
output:

1 - 2: 2

2 - 5: 2

2 - 3: 3

3 - 4: 3

0 - 1: 4

Result:

Thus the program was executed successfully.

You might also like