You are on page 1of 64

DEPARTMENT OF ARTIFICIAL

INTELLIGENCE AND DATA


SCIENCE

AD3271 - DATA STRUCTURES


DESIGN LABORATORY

REGULATION - 2021

PREPARED BY HOD
CK COLLEGE OF ENGINEERING AND TECHNOLOGY
(JAYARAM NAGAR CHELLENGUPPAM)
CUDDALORE - 607 003

DEPARTMENT OF ARTIFICIAL INTELLIGENCE AND DATA


SCIENCE

AD3271 - DATA STRUCTURES DESIGN LABORATORY

NAME :

REGISTER NO :
CK COLLEGE OF ENGINEERING AND TECHNOLOGY
(JAYARAM NAGAR CHELLENGUPPAM)CUDDALORE - 607 003

BONAFIDE CERTIFICATE

NAME :

REGISTER NO :

PROGRAMME :

SUBJECT CODE AND NAME :

DEPARTMENT :

SEMESTER :

Certified that this is the bonafide record of work done by

Mr. /Ms. Of Semester in the Department of


ARTIFICIAL INTELLIGENCE AND DATA SCIENCE of this college. AD3271 - DATA
STRUCTURES DESIGN LABORATORY during the academic year .

Signature of Faculty-in-charge Signature of H.O.D

Submitted for Practical Examination held on

Internal Examiner External Examiner


TABLE OF CONTENT
SL EX
NO NO DATE TITLE SIGN

1 1A CALCULATE EB BILL FOR GIVEN TARRIF

2 1B BASIC OPERATIONS OF CALCULATOR

3 2A FACTORIAL CALCULATION USING RECURSION

4 2B TOWER OF HONOI USING RECURSION

5 3 SEARCH ELEMENT IN A LIST USING ARRAY

6 4A CREATE LINKED LIST WITH N ELEMENTS

7 4B SEARCH KEY ELEMENTS IN LINKED LIST

8 5A INSERT ELEMENT INTO A STACK

9 5B IMPLEMENT QUEUE OPERATION

10 6A APPLICATIONS OF LIST ADT

11 6B APPLICATIONS OF STSCK ADT

12 6C APPLICATIONS OF QUEUE ADT

13 7A SORTING ALGORITHM (INSERTION SORT)

14 7B SEARCHING ALGORITHM(LINEAR SEARCH)

15 8 HASH TABLE

16 9 TREE REPRESENTATION AND TRAVERSAL ALGORITHM

17 10 BINARY SEARCH TREE

18 11A MIN HEAP

19 11B MAX HEAP

20 12A GRAPG REPRESENTATION AND TRAVERSAL ALGORITHM


DEPTH FIRST SEARCH ALGORITHM

21 12B BREATH FIRST SEARCH ALGORITHM

22 13A
SHORTEST PATH ALGORITHM
BELLMAN FORD ALGORITHM
DIGIKSTRA ALGORITHM
23 13B

24 14A MINIMUM SPANNING TREE


PRIMS ALGORITHM

25 14B KRUSKALS ALGORITHM


COURSE OBJECTIVES AND OUTCOMES

OBJECTIVES:

 To implement ADTs in Python

 To design and implement linear data structures – lists, stacks, and queues

 To implement sorting, searching and hashing algorithm

 To solve problems using tree and graph structures

OUTCOMES:

At the end of the course, the students will be able

 Design and implement various mobile applications using emulators.

 Implement ADTs as Python classes

 Design, implement, and analyse linear data structures, such as lists, queues, and stacks,

according to the needs of different applications

 Design, implement, and analyse efficient tree structures to meet requirements such as

searching, indexing, and sorting

 Model problems as graph problems and implement efficient graph algorithms to solve

theme.
EX: NO: 1A
SIMPLE ADTS AS PYTHON CLASSES
DATE:

Aim:

Write a Python program to calculate electricity bill for a given tariff.


 1 to 100 units – Rs. 10

 100 to 200 units – Rs. 15

 200 to 300 units – Rs.20

 above 300 units – Rs. 25

Algorithm:

1. Start

2. Accept the number of units as input from the user and store it in the variable 'units.'

3. Print "Payable Amount is : "

4. Call the function 'calculateBill' with the 'units' as an argument.

5. The 'calculateBill' function:

- Start
- Check if 'units' is less than or equal to 100.
- If true, multiply 'units' by 10 and return the result.
- Check if 'units' is less than or equal to 200.
- If true, calculate the bill using the formula:
((100 * 10) + (units - 100) * 15)
- Return the result.
- Check if 'units' is less than or equal to 300.
- If true, calculate the bill using the formula:
((100 * 10) + (100 * 15) + (units - 200) * 20)
- Return the result.
- If none of the above conditions are met, calculate the bill using the formula:
((100 * 10) + (100 * 15) + (100 * 20) + (units - 300) * 25)
- Return the result.
- End
6. Print the result returned by the 'calculateBill' function.

7. Stop.
Program:

def calculateBill(units):

if (units <= 100):


return units * 10;
elif (units <= 200):
return ((100 * 10) + (units - 100) * 15);
elif (units <= 300):
return ((100 * 10) + (100 * 15) + (units - 200) * 20);
elif (units > 300):
return ((100 * 10) + (100 * 15) + (100 * 20) + (units - 300) * 25);
return 0;

# Driver Code
units=int(input("Enter number of units:"))

print(“Payable Amount is : ”)
print(calculateBill(units));

Output:

Enter number of units:320


Payable Amount is :
5000

Result:
Thus, the Python program for to calculate electricity bill has been implemented successfully.
EX: NO: 1B
SIMPLE ADTS AS PYTHON CLASSES
DATE:

AIM:
To write a Python program for basic operations of calculator.

ALGORITHM:
1. Create a class named `cal` with the following methods:
- `__init__(self, a, b)`: Initialize the class with two input parameters, `a` and `b`.
- `add(self)`: Add `a` and `b` and return the result.
- `sub(self)`: Subtract `b` from `a` and return the result.
- `mul(self)`: Multiply `a` and `b` and return the result.
- `div(self)`: Divide `a` by `b` and return the result.
2. Prompt the user to enter two numbers (`a` and `b`).
3. Create an instance of the `cal` class with the provided input numbers.
4. Set `choice` variable to 1.
5. Start a while loop with the condition `choice != 0` to display the menu and perform calculations until
the user chooses to exit.
6. Inside the loop:
- Print the menu options (0-4) for the user to select from.
- Prompt the user to enter their choice.
- Use conditional statements to determine the user's choice and perform the corresponding calculation
using the methods of the `cal` class.
- If the choice is 0, print "Exiting!" and exit the loop.
- If the choice is not in the range 0-4, print "Invalid choice!!".
- Print a blank line for formatting purposes.
7. After the loop ends, the program execution is complete.

PROGRAM:
class cal():
def __init__(self,a,b):
self.a=a
self.b=b
def add(self):
return self.a+self.b
def mul(self):
return self.a*self.b
def div(self):
return self.a/self.b
def sub(self):
return self.a-self.b

a=int(input("Enter first number: "))


b=int(input("Enter second number: "))
obj=cal(a,b)
choice=1
while choice!=0:
print("0. Exit")
print("1. Add")
print("2. Subtraction")
print("3. Multiplication")
print("4. Division")
choice=int(input("Enter choice: "))
if choice==1:
print("Result: ",obj.add())
elif choice==2:
print("Result: ",obj.sub())
elif choice==3:
print("Result: ",obj.mul())
elif choice==4:
print("Result: ",round(obj.div(),2))
elif choice==0:
print("Exiting!")
else:
print("Invalid choice!!")
print()

Output:
Enter first number: 25
Enter second number: 5
0. Exit
1. Add
2. Subtraction
3. Multiplication
4. Division
Enter choice: 4
Result: 5.0

0. Exit
1. Add
2. Subtraction
3. Multiplication
4. Division

RESULT:
Thus, the Python program for basic operations of calculator has been implemented
successfully.
EX: NO: 2 A IMPLEMENTATION OF SIMPLE RECURSIVE
ALGORITHMS IN PYTHON
DATE:
Factorial

AIM:
To write a python program takes a number and determines the factorial of the number using
recursion.

ALGORITHM:
1. Take a number from the user and store it in a variable.
2. Pass the number as an argument to a recursive factorial function.
3. Define the base condition as the number to be lesser than or equal to 1 and return 1 if it is.
4. Otherwise call the function recursively with the number minus 1 multiplied by the number
itself.
5. Then return the result and print the factorial of the number.
6. Exit.

PROGRAM:
def factorial(x):
if x == 1:
return 1
else:
return (x * factorial(x-1))
num = int(input("Enter a number: "))
result = factorial(num)
print("The factorial of", num, "is", result)

OUTPUT:

Case 1:
Enter number:5
Factorial:
120

Case 2:
Enter number:9
Factorial:
362880

RESULT:
Thus, the Python program that takes a number and determines the factorial of the number using
recursion has been implemented successfully.
EX: NO: 2 B IMPLEMENTATION OF SIMPLE RECURSIVE
ALGORITHMS IN PYTHON
DATE:
Tower of Hanoi

AIM:
To write a Python program for Tower of Hanoi using recursion.

ALGORITHM:

1. The function `tower_of_hanoi` takes four parameters: `disks` (the number of disks to be moved),
`source` (the rod from which to move the disks), `auxiliary` (the auxiliary rod), and `target` (the rod to
which the disks should be moved).

2. If there is only one disk (`disks == 1`), it prints the instruction to move the disk directly from the source
rod to the target rod and returns.

3. Otherwise, it recursively calls `tower_of_hanoi` with `disks - 1` disks, moving them from the source rod
to the auxiliary rod, using the target rod as the temporary storage.

4. Then, it prints the instruction to move the remaining largest disk from the source rod to the target rod.

5. Finally, it recursively calls `tower_of_hanoi` with `disks - 1` disks, moving them from the auxiliary rod
to the target rod, using the source rod as the temporary storage.

6. The user is prompted to enter the number of disks to solve the Tower of Hanoi problem for, and the
function `tower_of_hanoi` is called with the provided inputs for source, auxiliary, and target rods ('A', 'B',
'C' respectively).

PROGRAM:
def tower_of_hanoi(disks, source, auxiliary, target):
if(disks == 1):
print('Move disk 1 from rod {} to rod {}.'.format(source, target))
return
tower_of_hanoi(disks - 1, source, target, auxiliary)
print('Move disk {} from rod {} to rod {}.'.format(disks, source, target))
tower_of_hanoi(disks - 1, auxiliary, source, target)
disks = int(input('Enter the number of disks: '))
tower_of_hanoi(disks, 'A', 'B', 'C')
OUTPUT:

Enter the number of disks: 3


Move disk 1 from rod A to rod C.
Move disk 2 from rod A to rod B.
Move disk 1 from rod C to rod B.
Move disk 3 from rod A to rod C.
Move disk 1 from rod B to rod A.
Move disk 2 from rod B to rod C.
Move disk 1 from rod A to rod C.

RESULT:
Thus, the Python program Tower of Hanoi using recursion has been implemented successfully.
EX: NO: 3
IMPLEMENTATION OF LIST USING
DATE: ARRAYS IN PYTHON

AIM:

To write a Python program to search element in a list using arrays.

ALGORITHM:
1. Algorithm for `SearchByIndex`:
- Input: `array_val` (array), `index_val` (integer)
- Output: `search_value` (value at the specified index in the array)
1. Set `item_index` to `index_val`
2. Set `n` to the length of `array_val`
3. Set `search_index` to 0
4. Set `search_value` to 'undefined'
5. While `search_index` is less than `n`, do the following:
- If `search_index` is equal to `item_index`, then:
- Set `search_value` to `array_val[search_index]`
- Break the loop
- Increment `search_index` by 1
6. Return `search_value`

2. Algorithm for `searchByValue`:


- Input: `array_val` (array), `item` (value to search for)
- Output: `search_index` (index of the first occurrence of the value in the array)
1. Set `n` to the length of `array_val`
2. Set `search_value` to `item`
3. Set `array_index` to 0
4. Set `search_index` to 'undefined'
5. While `array_index` is less than `n`, do the following:
- If `array_val[array_index]` is equal to `search_value`, then:
- Set `search_index` to `array_index`
- Break the loop
- Increment `array_index` by 1
6. Return `search_index`

PROGRAM:
def SearchByIndex(array_val, index_val) :
item_index= index_val;
n = len(array_val);
search_index = 0;
search_value = 'undefined';
while( search_index < n) :
if( search_index == item_index ) :
search_value = array_val[search_index]
break;
search_index = search_index + 1;
return search_value;

def searchByValue(array_val, item) :


n = len(array_val);
search_value = item;
array_index = 0
search_index= 'undefined';
while( array_index < n ) :
if( array_val[array_index] == search_value ):
search_index = array_index
break;
array_index = array_index + 1;
return search_index;
print("///////////////searchByIndex in an Array ////////////////")
number_array = [4, 5, 2, 7, 9, 13];
print("=========== Original Array =========")
for idex, item in enumerate(number_array):

print(" Array [", idex , "] ", item)

print("Array Item '", item , "' is in the position ", searchByValue(number_array, 13))

searchByValue(number_array, 9)
print("///////////////searchByValue in an Array ///////////////")

string_array = ["start", "to", "study", "from", "basics"];


print("=========== Original Array =========")
for idex, item in enumerate(string_array):
print(" Array [", idex , "] ", item)
print("Array Item '", item ,"' is in the position ", searchByValue(string_array, "basics")) # search by index
OUTPUT:
///////////////searchByIndex in an Array ////////////////

=========== Original Array =========


Array [ 0 ] 4
Array [ 1 ] 5
Array [ 2 ] 2
Array [ 3 ] 7
Array [ 4 ] 9
Array [ 5 ] 13
Array Item ' 13 ' is in the position 5

///////////////searchByValue in an Array ///////////////

=========== Original Array =========


Array [ 0 ] start
Array [ 1 ] to
Array [ 2 ] study
Array [ 3 ] from
Array [ 4 ] basics
Array Item ' basics ' is in the position 4

RESULT:
Thus, the Python program for search element in a list using arrays has been implemented successfully.
EX: NO: 4 A

DATE:
IMPLEMENTATION OF LINKED LIST INPYTHON

AIM:
To write a Python program to create linked list with n elements.

ALGORITHM:
1. Create a class called `Node`:
- Define the `__init__` method that initializes the node with the given data and sets the `next` attribute to
`None`.
2. Create a class called `LinkedList`:
- Define the `__init__` method that initializes the linked list with `head` and `last_node` attributes set to
`None`.
- Define the `append` method that takes in data and adds it to the linked list:
- If `last_node` is `None`, create a new node with the given data and set it as the `head` and `last_node`.
- Otherwise, create a new node with the given data and set `last_node.next` to the new node. Update
`last_node` to the new node.
- Define the `display` method that prints the data in the linked list:
- Set `current` to `head`.
- While `current` is not `None`, print `current.data` and update `current` to `current.next`.
3. Create an instance of the `LinkedList` class called `a_llist`.
4. Read the number of elements to be added from the user and store it in `n`.
5. Iterate `n` times using a `for` loop:
- Read the data item from the user and store it in `data`.
- Call the `append` method on `a_llist` with `data` as the argument.
6. Print "The linked list: " without a newline.
7. Call the `display` method on `a_llist`.

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

class LinkedList:
def __init__(self):
self.head = None
self.last_node = None

def append(self, data):


if self.last_node is None:
self.head = Node(data)
self.last_node = self.head
else:
self.last_node.next = Node(data)
self.last_node = self.last_node.next

def display(self):
current = self.head
while current is not None:
print(current.data, end = ' ')
current = current.next

a_llist = LinkedList()
n = int(input('How many elements would you like to add? '))
for i in range(n):
data = int(input('Enter data item: '))
a_llist.append(data)
print('The linked list: ', end = '')
a_llist.display()

OUTPUT:
How many elements would you like to add? 5
Enter data item: 10
Enter data item: 20
Enter data item: 30
Enter data item: 40
Enter data item: 50
The linked list: 10 20 30 40 50

RESULT:
Thus, the Python program for create linked list with n elements has been implemented successfully.
EX: NO: 4 B

DATE:
IMPLEMENTATION OF LINKED LIST INPYTHON

AIM:
To write a Python program to search key element in a linked list.

ALGORITHM:
1. Define a class called `Node` with attributes `data` and `next`.
2. Implement the `__init__()` method of the `Node` class to initialize the `data` attribute with the given
argument and set `next` to `None`.
3. Define a class called `LinkedList` with an attribute `head`.
4. Implement the `__init__()` method of the `LinkedList` class to initialize `head` as `None`.
5. Implement the `push()` method of the `LinkedList` class:
- Create a new node with the given data.
- Set the `next` attribute of the new node to the current `head` node.
- Update `head` to point to the new node.
6. Implement the `search()` method of the `LinkedList` class:
- Initialize a variable `current` with the `head` node.
- Iterate through the linked list by checking if `current` is not `None`.
- If the `data` of the current node is equal to the given value `x`, return `True`.
- Otherwise, move to the next node by updating `current` to the next node.
- If the loop completes without finding a match, return `False`.
7. Create an instance of the `LinkedList` class called `llist`.
8. Use the `push()` method to add elements to the linked list: 10, 30, 11, 21, and 14.
9. Use the `search()` method to check if the value 10 exists in the linked list.
10. If the value is found, print "Yes"; otherwise, print "No".

PROGRAM:

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

class LinkedList:
def __init__(self):
self.head = None

def push(self, new_data):


new_node = Node(new_data)
new_node.next = self.head
self.head = new_node

def search(self, x):


current = self.head
while current is not None:
if current.data == x:
return True
current = current.next
return False

if __name__ == '__main__':
llist = LinkedList()

# Use push() to construct list


# 14->21->11->30->10
llist.push(10)
llist.push(30)
llist.push(11)
llist.push(21)
llist.push(14)

if llist.search(10):
print("Yes")
else:
print("No")

OUTPUT:
Yes

RESULT:
Thus, the Python program for search key element in a linked list has been implemented successfully.
EX: NO: 5 A

DATE:
IMPLEMENTATION OF STACK IN PYTHON

AIM:
To write a Python program to insert elements into stack.

ALGORITHM:
The provided code implements a basic stack data structure using a list in Python. The stack supports the
following operations: creating an empty stack, checking if the stack is empty, pushing an item onto the
stack, and popping an item from the stack. Here's an algorithmic representation of the code:

1. Create an empty stack:


- Initialize an empty list as the stack.
- Return the stack.
2. Check if the stack is empty:
- Return True if the length of the stack is 0.
- Return False otherwise.
3. Push an item onto the stack:
- Append the given item to the stack.
- Print a message indicating the item has been pushed.
4. Pop an item from the stack:
- Check if the stack is empty.
- If it is, return "stack is empty".
- Remove and return the last item from the stack.

PROGRAM:

def create_stack():
stack = []
return stack
def check_empty(stack):
return len(stack) == 0
def push(stack, item):
stack.append(item)
print("pushed item: " + item)
def pop(stack):
if (check_empty(stack)):
return "stack is empty"
return stack.pop()
stack = create_stack()
push(stack, str(1))
push(stack, str(2))
push(stack, str(3))
push(stack, str(4))
print("popped item: " + pop(stack))
print("stack after popping an element: " + str(stack))

OUTPUT:
Pushed item: 1
Pushed item: 2
Pushed item: 3
Pushed item: 4
Popped item: 4
Stack after popping an element: [‘1’, ‘2’, ‘3’]

RESULT:
Thus, the Python program for insert elements into stack has been implemented successfully.
EX: NO: 5 B

DATE:
IMPLEMENTATION OF QUEUE IN PYTHON

AIM:
To write a Python program to implement queue.

ALGORITHM:
1. Create a class named `Queue`.
2. Inside the `Queue` class, define the `__init__` method that initializes an empty list `queue` as an
instance variable.
3. Define the `enqueue` method that takes an item as a parameter and appends it to the end of the `queue`
list.
4. Define the `dequeue` method that removes and returns the first element from the `queue` list. If the
`queue` is empty, return `None`.
5. Define the `display` method that prints the contents of the `queue` list.
6. Define the `size` method that returns the length of the `queue` list.
7. Create an instance of the `Queue` class called `q`.
8. Use the `enqueue` method of `q` to add elements 1, 2, 3, 4, and 5 to the queue.
9. Use the `display` method of `q` to print the contents of the queue.
10. Use the `dequeue` method of `q` to remove the first element from the queue.
11. Print "After removing an element".
12. Use the `display` method of `q` to print the contents of the queue.

PROGRAM:

class Queue:

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

# Add an element
def enqueue(self, item):
self.queue.append(item)

# Remove an element
def dequeue(self):
if len(self.queue) < 1:
return None
return self.queue.pop(0)

# Display the queue


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

def size(self):
return len(self.queue)
q = Queue()
q.enqueue(1)
q.enqueue(2)
q.enqueue(3)
q.enqueue(4)
q.enqueue(5)
q.display()
q.dequeue()

print("After removing an element")


q.display()

OUTPUT:

[1, 2, 3, 4, 5]
After removing an element
[2, 3, 4, 5]

RESULT:
Thus, the Python program for to implement queue has been implemented successfully.
EX: NO: 6 A APPLICATIONS OF LIST, STACK AND QUEUE ADTS

DATE: A. APPLICATIONS OF LIST ADT

AIM:

To write a Python program for implementation of polynomial ADT.

ALGORITHM:
1: Start the program
2: Get the coefficients and powers for the two polynomials to be added.
3: Add the coefficients of the respective powers.
4: Display the added polynomial. Step5: Terminate the program.

PROGRAM:
def add(A, B, m, n):
size = max(m, n)
sum = [0 for i in range(size)]

for i in range(0, m, 1):


sum[i] = A[i]

for i in range(n):
sum[i] += B[i]

return sum

def printPoly(poly, n):


for i in range(n):
print(poly[i], end="")
if i != 0:
print("x^", i, end="")
if i != n - 1:
print(" + ", end="")
print()

if __name__ == '__main__':
A = [5, 0, 10, 6]
B = [1, 2, 4]
m = len(A)
n = len(B)

print("First polynomial is")


printPoly(A, m)

print("\n", end="")
print("Second polynomial is")
printPoly(B, n)

print("\n", end="")

sum = add(A, B, m, n)
size = max(m, n)

print("Sum polynomial is")


printPoly(sum, 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 Python program for implementation of polynomial ADT has been executed
successfully.
EX: NO: 6 B APPLICATIONS OF LIST, STACK AND QUEUE ADTS

DATE: B. APPLICATIONS OF STACK ADT

A. AIM:

To write a Python program to Check if Expression is Correctly Parenthesized


.
ALGORITHM:
1. Create a class Stack with instance variable items initialized to an empty list.
2. Define methods push, pop and is_empty inside the class Stack.
3. The method push appends data to items.
4. The method pop pops the first element in items.
5. The method is_empty returns True only if items is empty.
6. Prompt the user for an expression.
7. Iterate through the characters of the expression and push to the stack if an open parenthesis is
encountered and pop if a close parenthesis is encountered.
8. Determine whether the expression has balanced parentheses.

PROGRAM:
class Stack:
def __init__(self):
self.items = []

def is_empty(self):
return self.items == []

def push(self, data):


self.items.append(data)

def pop(self):
return self.items.pop()

s = Stack()
exp = input('Please enter the expression: ')

is_balanced = True # Initialize is_balanced outside the loop

for c in exp:
if c == '(':
s.push(1)
elif c == ')':
if s.is_empty():
is_balanced = False
break
s.pop()
if s.is_empty() and is_balanced: # Check if the stack is empty and is_balanced
print('Expression is correctly parenthesized.')
else:
print('Expression is not correctly parenthesized.')

OUTPUT:
Case 1:
Please enter the expression: (3 + 4 * (1 + (2))/(7 * (8 + 9)))
Expression is correctly parenthesized.

Case 2:
Please enter the expression: (a + b))(3)
Expression is not correctly parenthesized.

Case 3:
Please enter the expression: (4 + (3 * 2)
Expression is not correctly parenthesized

RESULT:
Thus, the Python program for implementation of whether Expression is Correctly Parenthesized
has been executed successfully.
EX: NO: 6 C APPLICATIONS OF LIST, STACK AND QUEUE ADTS

DATE: C. APPLICATIONS OF QUEUE ADT

B. AIM:

To write a Python program that creates a dequeue and allows the user to perform append and pop
operations on it from both sides.
.
ALGORITHM:
1. Create a class Dequeue with instance variable items initialized to an empty list.
2. Define methods append, append_left, pop, pop_left and is_empty inside the class Dequeue.
3. The method append appends data to items from the right.
4. The method append_left appends data to items from the left.
5. The method pop pops from the right from items.
6. The method pop_left pops from the left from items.
7. The method is_empty returns True only if items is empty.

PROGRAM:
class Dequeue:
def __init__(self):
self.items = []

def is_empty(self):
return self.items == []

def append(self, data):


self.items.append(data)

def append_left(self, data):


self.items.insert(0, data)

def pop(self):
return self.items.pop()

def pop_left(self):
return self.items.pop(0)

q = Dequeue()
print('Menu')
print('append <value>')
print('appendleft <value>')
print('pop')
print('popleft')
print('quit')
while True:
do = input('What would you like to do? ').split()

operation = do[0].strip().lower()
if operation == 'append':
q.append(int(do[1]))
elif operation == 'appendleft':
q.append_left(int(do[1]))
elif operation == 'pop':
if q.is_empty():
print('Dequeue is empty.')
else:
print('Popped value from right:', q.pop())
elif operation == 'popleft':
if q.is_empty():
print('Dequeue is empty.')
else:
print('Popped value from left:', q.pop_left())
elif operation == 'quit':
break

OUTPUT:

Case 1:
Menu
append <value>
append left <value>
pop
pop left
quit
What would you like to do? append 3
What would you like to do? append 4
What would you like to do? append left 2
What would you like to do? append left 1
What would you like to do? pop
Popped value from right: 4
What would you like to do? pop left
Popped value from left: 1
What would you like to do? pop
Popped value from right: 3
What would you like to do? pop left
Popped value from left: 2
What would you like to do? pop
Dequeue is empty.
What would you like to do? quit
Case 2:
Menu
append <value>
append left <value>
pop
pop left
quit
What would you like to do? append 1
What would you like to do? append 2
What would you like to do? pop
Popped value from right: 2
What would you like to do? pop
Popped value from right: 1
What would you like to do? append left 1
What would you like to do? append left 2
What would you like to do? pop
Popped value from right: 1
What would you like to do? pop
Popped value from right: 2
What would you like to do? append 1
What would you like to do? append 2
What would you like to do? popleft
Popped value from left: 1
What would you like to do? popleft
Popped value from left: 2
What would you like to do? quit

RESULT:
Thus, the Python program for implementation of dequeue and allows the user to perform append
and pop operations on it from both sides. has been executed successfully.
EX: NO: 7 A SORTING AND SEARCHING ALGORITHMS

DATE: A.SORTING ALGORITHM (INSERTION SORT)

AIM:

To Perform Insertion Sorting in Python Programming.

ALGORITHM:

Step 1: Start
Step 2: Define list of elements(alist)
Step 3: Take first element find its appropriate position and insert them
Step 4: Repeat till every element is sorted
Step 5: Print the list of elements
Step 6: Stop

PROGRAM:

def insertionSort(lst):
for index in range(1, len(lst)):
currentvalue = lst[index]
position = index

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


lst[position] = lst[position - 1]
position = position - 1

lst[position] = currentvalue

lst = [54, 26, 93, 17, 77, 31, 44, 55, 20]
insertionSort(lst)
print(lst)

OUTPUT:

17,20,26,31,44,54,55,77,93

RESULT:

Thus, the python program to perform Insertion Sort is created and executed successfully.
EX: NO: 7 B SORTING AND SEARCHING ALGORITHMS

DATE: A. SEARCHING ALGORITHM (LINEAR SEARCH)

A. AIM:

To Perform a Linear Search in Python Programming

ALGORITHM:

Step 1: Start
Step 2: Define a list of elements list_of_elements[]
Step 3: Get the element to be checked from the user(x)
Step 4: Compare the elements with each element in the list
Step 5: If found print found and print index number
Step 6: Else print element not found
Step 6: Stop

PROGRAM:

list_of_elements = [4, 2, 8, 9, 3, 7]
x = int(input("Enter number to search: "))
found = False

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 not found:
print("%d is not in the list" % x)

OUTPUT:

Enter element to search:4


4 is found at 0th position

RESULT:

Thus, the python program to perform Linear Search is created and executed successfully.
EX: NO: 8

DATE:
HASH TABLE

AIM:
To write a python program to implement the concept of hashing using separate chaining.
ALGORITHM:
1: Start
2: Create Table size
3: Create hash function
4: To insert a node into the hash table, we need to find the hash index for the given key. And it
could be calculated using the hash function.
5: Display hash entry.
6: Stop
PROGRAM:
def display_hash(hashTable):
for i in range(len(hashTable)):
print(i, end=" ")
for j in hashTable[i]:
print("-->", end=" ")
print(j, end=" ")
print()

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

def Hashing(keyvalue):
return keyvalue % len(HashTable)

def insert(HashTable, keyvalue, value):


hash_key = Hashing(keyvalue)
HashTable[hash_key].append(value)

insert(HashTable, 10, 'Allahabad')


insert(HashTable, 25, 'Mumbai')
insert(HashTable, 20, 'Mathura')
insert(HashTable, 9, 'Delhi')
insert(HashTable, 21, 'Punjab')
insert(HashTable, 21, 'Noida')

display_hash(HashTable)
OUTPUT:
0 --> Allahabad --> Mathura
1 --> Punjab --> Noida
2
3
4
5 --> Mumbai
6
7
8
9 --> Delhi

RESULT:
Thus, the python program to implement the concept of hashing using separate chaining. has been
implemented successfully.
EX: NO: 9
TREE REPRESENTATION AND TRAVERSAL
DATE: ALGORITHM

AIM:

To write a python program to implement the tree representation and traversal algorithm

ALGORITHM:

1. The left sub tree of a node contains smaller nodes than a root node.
2. The right sub tree of a node contains greater nodes than a root node.
3. Both the left and right sub trees must also be binary search trees.
4. There are three types of tree traversals: Preorder, Postorder, and Inorder.

Pre-order traversal
Algorithm:
1. Visit the root (we will print it when we visit to show the order of visiting)
2. Traverse the left subtree in pre-order
3. Traverse the right subtree in pre-order

In-order traversal
Visit the root node in between the left and right node (in)
Algorithm:
1. Traverse the left subtree in in-order
2. Visit the root (we will print it when we visit to show the order of visiting)
3. Traverse the right subtree in in-order

Post-order traversal
Visit the root node after (post) visiting the left and right subtree.
Algorithm:
1. Traverse the left subtree in in-order
2. Traverse the right subtree in in-order
3. Visit the root (we will print it when we visit to show the order of visiting)

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)
printInorder(root.right)

def printPostorder(root):
if root:
printPostorder(root.left)
printPostorder(root.right)
print(root.val)

def printPreorder(root):
if root:
print(root.val)
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)

print("Preorder 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 python program to implement the concept of tree representation and traversal algorithm.
has been implemented successfully.
EX: NO: 10

DATE:
BINARY SEARCH TREE

AIM:
To write a python program creates a binary search tree and presents a menu to the user to
perform insertion, deletion and inorder traversal operations.

ALGORITHM:
1. Create a class BSTNode with instance variables key, left, right and parent.
2. Define methods insert, inorder, replace_node_of_parent, find_min, remove and search in
BSTNode.
3. The method insert takes a node as argument and inserts that node in the BST with the
BSTNode object as root.
4. The method inorder displays the inorder traversal of the BST with the BSTNode object as
root.
5. The method replace_node_of_parent takes a node as argument and replaces the current object
in the BST with the node.
6. The method find_min finds the the left-most node in the BST with the BSTNode object as
root.
7. The method remove removes the current BSTNode object from the BST.
8. The method search takes a key as argument and returns the node with that key in the BST with
the BSTNode object as root.
9. Create a class BSTree with instance variable root.
10. Define methods inorder, add, remove and search in BSTree.
11. The method inorder calls the inorder method of the root node.

PROGRAM:
class BSTNode:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
self.parent = None

def insert(self, node):


if self.key > node.key:
if self.left is None:
self.left = node
node.parent = self
else:
self.left.insert(node)
elif self.key < node.key:
if self.right is None:
self.right = node
node.parent = self
else:
self.right.insert(node)

def inorder(self):
if self.left is not None:
self.left.inorder()
print(self.key, end=' ')
if self.right is not None:
self.right.inorder()

def replace_node_of_parent(self, new_node):


if self.parent is not None:
if new_node is not None:
new_node.parent = self.parent
if self.parent.left == self:
self.parent.left = new_node
elif self.parent.right == self:
self.parent.right = new_node
else:
self.key = new_node.key
self.left = new_node.left
self.right = new_node.right
if new_node.left is not None:
new_node.left.parent = self
if new_node.right is not None:
new_node.right.parent = self

def find_min(self):
current = self
while current.left is not None:
current = current.left
return current

def remove(self):
if self.left is not None and self.right is not None:
successor = self.right.find_min()
self.key = successor.key
successor.remove()
elif self.left is not None:
self.replace_node_of_parent(self.left)
elif self.right is not None:
self.replace_node_of_parent(self.right)
else:
self.replace_node_of_parent(None)

def search(self, key):


if self.key > key:
if self.left is not None:
return self.left.search(key)
else:
return None
elif self.key < key:
if self.right is not None:
return self.right.search(key)
else:
return None
return self

class BSTree:
def __init__(self):
self.root = None

def inorder(self):
if self.root is not None:
self.root.inorder()

def add(self, key):


new_node = BSTNode(key)
if self.root is None:
self.root = new_node
else:
self.root.insert(new_node)

def remove(self, key):


to_remove = self.search(key)
if self.root == to_remove and self.root.left is None and self.root.right is None:
self.root = None
else:
to_remove.remove()

def search(self, key):


if self.root is not None:
return self.root.search(key)

bstree = BSTree()

print('Menu (this assumes no duplicate keys)')


print('add <key>')
print('remove <key>')
print('inorder')
print('quit')

while True:
do = input('What would you like to do? ').split()

operation = do[0].strip().lower()
if operation == 'add':
key = int(do[1])
bstree.add(key)
elif operation == 'remove':
key = int(do[1])
bstree.remove(key)
elif operation == 'inorder':
print('Inorder traversal: ', end='')
bstree.inorder()
print()
elif operation == 'quit':
break

OUTPUT:
Case 1:
Menu (this assumes no duplicate keys)
add <key>
remove <key>
inorder
quit
What would you like to do? add 5
What would you like to do? add 1
What would you like to do? add 10
What would you like to do? add 7
What would you like to do? add 3
What would you like to do? inorder
Inorder traversal: 1 3 5 7 10
What would you like to do? remove 3
What would you like to do? remove 7
What would you like to do? inorder
Inorder traversal: 1 5 10
What would you like to do? remove 5
What would you like to do? inorder
Inorder traversal: 1 10
What would you like to do? quit

Case 2:
Menu (this assumes no duplicate keys)
add <key>
remove <key>
inorder
quit
What would you like to do? add 2
What would you like to do? add 8
What would you like to do? inorder
Inorder traversal: 2 8
What would you like to do? add 5
What would you like to do? inorder
Inorder traversal: 2 5 8
What would you like to do? remove 2
What would you like to do? remove 8
What would you like to do? inorder
Inorder traversal: 5
What would you like to do? remove 5
What would you like to do? inorder
Inorder traversal:
What would you like to do? quit

RESULT:

Thus, the python program to implement the concept of binary search tree. has been implemented
successfully.
EX: NO: 11 A
IMPLEMENTATION OF HEAPS
DATE: A.MIN HEAP

AIM:

To write a Python program to find min heap.

ALGORITHM:
1. Create a class called MinHeap.
2. Initialize the class with the maximum size of the heap.
3. Initialize the size of the heap, an array to store the heap elements, and set the first element in the heap
array to a very small value.
4. Define helper functions:
a. parent(pos): Returns the position of the parent node for the node at the given position.
b. leftChild(pos): Returns the position of the left child node for the node at the given position.
c. rightChild(pos): Returns the position of the right child node for the node at the given position.
d. isLeaf(pos): Checks if the node at the given position is a leaf node.
e. swap(fpos, spos): Swaps the positions of two nodes in the heap array.
f. minHeapify(pos): Fixes the heap property at the given position by recursively swapping nodes to
satisfy the min-heap property.
5. Define an insert(element) function:
a. Check if the heap has reached its maximum size, and if so, return.
b. Increment the size of the heap and add the element at the next available position.
c. Perform swaps with the parent node until the element reaches its correct position in the heap.
6. Define a Print() function to print the contents of the heap.
7. Define a minHeap() function to build the min heap by calling minHeapify() on all non-leaf nodes in
reverse order.
8. Define a remove() function to remove and return the minimum element from the heap:
a. Store the minimum element (at the root) in a variable called "popped."
b. Replace the root element with the last element in the heap.
c. Decrement the size of the heap.
d. Call minHeapify() on the root to restore the min-heap property.
e. Return the stored minimum element.
9. In the main block:
a. Create a MinHeap object with a maximum size of 15.
b. Insert elements into the heap.
c. Build the min heap.
d. Print the contents of the heap.
e. Remove and print the minimum value from the heap.
PROGRAM:

import sys

class MinHeap:

def __init__(self, maxsize):


self.maxsize = maxsize
self.size = 0
self.Heap = [0]*(self.maxsize + 1)
self.Heap[0] = -1 * sys.maxsize
self.FRONT = 1

# Function to return the position of


# parent for the node currently
# at pos
def parent(self, pos):
return pos//2

# Function to return the position of


# the left child for the node currently
# at pos
def leftChild(self, pos):
return 2 * pos

# Function to return the position of


# the right child for the node currently
# at pos
def rightChild(self, pos):
return (2 * pos) + 1

# Function that returns true if the passed


# node is a leaf node
def isLeaf(self, pos):
return pos*2 > self.size

# Function to swap two nodes of the heap


def swap(self, fpos, spos):
self.Heap[fpos], self.Heap[spos] = self.Heap[spos], self.Heap[fpos]

# Function to heapify the node at pos


def minHeapify(self, pos):

# If the node is a non-leaf node and greater


# than any of its child
if not self.isLeaf(pos):
if (self.Heap[pos] > self.Heap[self.leftChild(pos)] or
self.Heap[pos] > self.Heap[self.rightChild(pos)]):
# Swap with the left child and heapify
# the left child
if self.Heap[self.leftChild(pos)] < self.Heap[self.rightChild(pos)]:
self.swap(pos, self.leftChild(pos))
self.minHeapify(self.leftChild(pos))

# Swap with the right child and heapify


# the right child
else:
self.swap(pos, self.rightChild(pos))
self.minHeapify(self.rightChild(pos))

# Function to insert a node into the heap


def insert(self, element):
if self.size >= self.maxsize :
return
self.size+= 1
self.Heap[self.size] = element

current = self.size

while self.Heap[current] < self.Heap[self.parent(current)]:


self.swap(current, self.parent(current))
current = self.parent(current)

# Function to print the contents of the heap


def Print(self):
for i in range(1, (self.size//2)+1):
print(" PARENT : "+ str(self.Heap[i])+" LEFT CHILD : "+
str(self.Heap[2 * i])+" RIGHT CHILD : "+
str(self.Heap[2 * i + 1]))

# Function to build the min heap using


# the minHeapify function
def minHeap(self):

for pos in range(self.size//2, 0, -1):


self.minHeapify(pos)

# Function to remove and return the minimum


# element from the heap
def remove(self):

popped = self.Heap[self.FRONT]
self.Heap[self.FRONT] = self.Heap[self.size]
self.size-= 1
self.minHeapify(self.FRONT)
return popped

# Driver Code
if __name__ == "__main__":

print('The minHeap is ')


minHeap = MinHeap(15)
minHeap.insert(5)
minHeap.insert(3)
minHeap.insert(17)
minHeap.insert(10)
minHeap.insert(84)
minHeap.insert(19)
minHeap.insert(6)
minHeap.insert(22)
minHeap.insert(9)
minHeap.minHeap()

minHeap.Print()
print("The Min val is " + str(minHeap.remove()))

OUTPUT:

The minHeap is
PARENT : 3 LEFT CHILD : 5 RIGHT CHILD : 6
PARENT : 5 LEFT CHILD : 9 RIGHT CHILD : 84
PARENT : 6 LEFT CHILD : 19 RIGHT CHILD : 17
PARENT : 9 LEFT CHILD : 22 RIGHT CHILD : 10
The Min val is 3

RESULT:
Thus, the python program to implement the concept of MIN heap has been implemented
successfully.
EX: NO: 11 B
IMPLEMENTATION OF HEAPS
DATE: A.MAX HEAP

AIM:
Write a Python program to implement max heap.

ALGORITHM:
1. Start by importing the `sys` module.
2. Define a class called `MaxHeap`.
3. In the `__init__` method of the class, initialize the maximum size, current size, heap list, and the root
index.
4. Define the `parent`, `leftChild`, and `rightChild` methods to calculate the parent, left child, and right
child indices for a given node index.
5. Define the `isLeaf` method to check if a node is a leaf node (i.e., it doesn't have any children).
6. Define the `swap` method to swap two nodes in the heap.
7. Define the `maxHeapify` method to heapify the heap at a given position. It compares the node with its
children and swaps it with the larger child if necessary. The process is repeated recursively until the heap
property is satisfied.
8. Define the `insert` method to insert an element into the heap. It adds the element at the next available
position and then restores the heap property by swapping the element with its parent until the heap
property is satisfied.
9. Define the `Print` method to print the contents of the heap. It iterates over the heap and prints each node
along with its left and right children.
10. Define the `extractMax` method to remove and return the maximum element from the heap. It replaces
the root node with the last node in the heap, reduces the size of the heap, and then calls `maxHeapify` to
restore the heap property.
11. In the driver code, create an instance of `MaxHeap` with a maximum size of 15.
12. Insert some elements into the heap using the `insert` method.
13. Print the contents of the heap using the `Print` method.
14. Remove and print the maximum element using the `extractMax` method.

PROGRAM:

import sys

class MaxHeap:

def __init__(self, maxsize):

self.maxsize = maxsize
self.size = 0
self.Heap = [0] * (self.maxsize + 1)
self.Heap[0] = sys.maxsize
self.FRONT = 1
# Function to return the position of
# parent for the node currently
# at pos
def parent(self, pos):

return pos // 2

# Function to return the position of


# the left child for the node currently
# at pos
def leftChild(self, pos):

return 2 * pos

# Function to return the position of


# the right child for the node currently
# at pos
def rightChild(self, pos):

return (2 * pos) + 1

# Function that returns true if the passed


# node is a leaf node
def isLeaf(self, pos):

if pos >= (self.size//2) and pos <= self.size:


return True
return False

# Function to swap two nodes of the heap


def swap(self, fpos, spos):

self.Heap[fpos], self.Heap[spos] = (self.Heap[spos],self.Heap[fpos])

# Function to heapify the node at pos


def maxHeapify(self, pos):

# If the node is a non-leaf node and smaller


# than any of its child
if not self.isLeaf(pos):
if (self.Heap[pos] < self.Heap[self.leftChild(pos)] or
self.Heap[pos] < self.Heap[self.rightChild(pos)]):

# Swap with the left child and heapify


# the left child
if (self.Heap[self.leftChild(pos)] >
self.Heap[self.rightChild(pos)]):
self.swap(pos, self.leftChild(pos))
self.maxHeapify(self.leftChild(pos))
# Swap with the right child and heapify
# the right child
else:
self.swap(pos, self.rightChild(pos))
self.maxHeapify(self.rightChild(pos))

# Function to insert a node into the heap


def insert(self, element):

if self.size >= self.maxsize:


return
self.size += 1
self.Heap[self.size] = element

current = self.size

while (self.Heap[current] >


self.Heap[self.parent(current)]):
self.swap(current, self.parent(current))
current = self.parent(current)

# Function to print the contents of the heap


def Print(self):

for i in range(1, (self.size // 2) + 1):


print(" PARENT : " + str(self.Heap[i]) +" LEFT CHILD : " + str(self.Heap[2 * i]) +
" RIGHT CHILD : " + str(self.Heap[2 * i + 1]))

# Function to remove and return the maximum


# element from the heap
def extractMax(self):

popped = self.Heap[self.FRONT]
self.Heap[self.FRONT] = self.Heap[self.size]
self.size -= 1
self.maxHeapify(self.FRONT)

return popped

# Driver Code
if __name__ == "__main__":

print('The maxHeap is ')

maxHeap = MaxHeap(15)
maxHeap.insert(5)
maxHeap.insert(3)
maxHeap.insert(17)
maxHeap.insert(10)
maxHeap.insert(84)
maxHeap.insert(19)
maxHeap.insert(6)
maxHeap.insert(22)
maxHeap.insert(9)

maxHeap.Print()

print("The Max val is " + str(maxHeap.extractMax()))

OUTPUT:

The maxHeap is
PARENT : 84 LEFT CHILD : 22 RIGHT CHILD : 19
PARENT : 22 LEFT CHILD : 17 RIGHT CHILD : 10
PARENT : 19 LEFT CHILD : 5 RIGHT CHILD : 6
PARENT : 17 LEFT CHILD : 3 RIGHT CHILD : 9
The Max val is 84

RESULT:
Thus, the python program to implement the concept of MAX heap has been implemented
successfully.
EX: NO: 12 A
GRAPH REPRESENTATION AND TRAVERSAL
ALGORITHM
DATE:
A.DEPTH FIRST SEARCH

AIM:
To write a Python program to implement depth first search. and breadth first search.

ALGORITHM:

1. Take the graph as input and find the adjacency list


2. Start at a random vertex and visit all nodes using depth first search (DFS) and then breadth
first search (BFS).
3. Use stack for DFS and queue for BFS.

PROGRAM:
from collections import defaultdict

class Graph:
def __init__(self):
self.graph = defaultdict(list)

def addEdge(self, u, v):


self.graph[u].append(v)

def DFSUtil(self, v, visited):


visited.add(v)
print(v, end=' ')

for neighbour in self.graph[v]:


if neighbour not in visited:
self.DFSUtil(neighbour, visited)

def DFS(self, v):


visited = set()
self.DFSUtil(v, visited)

g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)

print("Following is DFS (starting from vertex 2):")


g.DFS(2)
OUTPUT:

Following is DFS (starting from vertex 2):


2013

RESULT;
Thus, the Python program to implement depth first search has beenexecuted successfully.
EX: NO: 12 B GRAPH REPRESENTATION AND TRAVERSAL
ALGORITHM
DATE:
A.BREATH FIRST SEARCH

AIM:
To write a Python program to implement breadth first search.

ALGORITHM:

1. Take the graph as input and find the adjacency list


2. Start at a random vertex and visit all nodes using breadthfirst search (BFS).
3. Use queue for BFS.
4. Exit

PROGRAM:
from collections import defaultdict

class Graph:
def __init__(self):
self.graph = defaultdict(list)

def addEdge(self, u, v):


self.graph[u].append(v)

def BFS(self, s):


visited = [False] * (max(self.graph.keys()) + 1)
queue = []
queue.append(s)
visited[s] = True

while queue:
s = queue.pop(0)
print(s, end=" ")
for i in self.graph[s]:
if not visited[i]:
queue.append(i)
visited[i] = True

g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)

print("Following is Breadth First Traversal (starting from vertex 2)")


g.BFS(2)

OUTPUT:

Breadth First Traversal (starting from vertex 2)


2031

RESULT;
Thus, the Python program to implement depth first search has beenexecuted successfully.
EX: NO: 13 A SINGLE SOURCE SHORTEST PATH ALGORITHM

DATE: Bellman Ford Algorithm

AIM:
Write a Python program for single source shortest path using Bellman Ford Algorithm.

ALGORITHM:

1. Create a class named `Graph` with the following methods:


- `__init__(self, vertices)`: Initializes the graph object with the total number of vertices (`M`) and an
empty list to store the edges (`graph`).
- `add_edge(self, a, b, c)`: Adds an edge to the graph by appending `[a, b, c]` to the `graph` list, where `a`
and `b` are the vertices connected by the edge, and `c` is the weight of the edge.
- `print_solution(self, distance)`: Prints the shortest distance from the source vertex to each vertex in the
graph.
- `bellman_ford(self, src)`: Implements the Bellman-Ford algorithm to calculate the shortest paths. It
takes the source vertex (`src`) as input.
2. In the `bellman_ford` method, create a list `distance` initialized with infinity (`float("Inf")`) for each
vertex in the graph. Set the distance of the source vertex (`src`) to 0.
3. Perform relaxation of edges `M - 1` times, where `M` is the total number of vertices in the graph. In
each iteration, loop over each edge (`a`, `b`, `c`) in the `graph`. If the distance from the source vertex (`a`)
is not infinity and the distance from the source vertex plus the weight of the edge (`c`) is less than the
current distance to the destination vertex (`b`), update the distance to the destination vertex (`b`) with the
new shorter distance.
4. After the relaxation process, check for negative weight cycles. Loop over each edge (`a`, `b`, `c`) in the
`graph` again. If the distance from the source vertex (`a`) is not infinity and the distance from the source
vertex plus the weight of the edge (`c`) is less than the current distance to the destination vertex (`b`), it
means there is a negative weight cycle in the graph. In this case, print "Graph contains negative weight
cycle" and return.
5. If there are no negative weight cycles, call the `print_solution` method to print the shortest distance from
the source vertex to each vertex in the graph.
6. Create an instance of the `Graph` class with `5` vertices.
7. Add the edges to the graph using the `add_edge` method.
8. Run the Bellman-Ford algorithm on the graph with the source vertex `0` using the `bellman_ford`
method.

PROGRAM:
class Graph:
def __init__(self, vertices):
self.M = vertices # Total number of vertices in the graph
self.graph = [] # Array of edges

# Add edges

def add_edge(self, a, b, c):


self.graph.append([a, b, c])

# Print the solution


def print_solution(self, distance):
print("Vertex Distance from Source")
for k in range(self.M):
print("{0}\t\t{1}".format(k, distance[k]))

def bellman_ford(self, src):


distance = [float("Inf")] * self.M
distance[src] = 0
for _ in range(self.M - 1):
for a, b, c in self.graph:
if distance[a] != float("Inf") and distance[a] + c < distance[b]:
distance[b] = distance[a] + c
for a, b, c in self.graph:
if distance[a] != float("Inf") and distance[a] + c < distance[b]:
print("Graph contains negative weight cycle")
return

self.print_solution(distance)
g = Graph(5)
g.add_edge(0, 1, 2)
g.add_edge(0, 2, 4)
g.add_edge(1, 3, 2)
g.add_edge(2, 4, 3)
g.add_edge(2, 3, 4)
g.add_edge(4, 3, -5)
g.bellman_ford(0)

OUTPUT:

Vertex Distance from Source


0 0
1 2
2 4
3 2
4 7

RESULT:
Thus, the Python program to implement single source shortest path using Bellman Ford
Algorithm has been executed successfully.
EX: NO: 13 B
SINGLE SOURCE SHORTEST PATH ALGORITHM
DATE:
DIJIKTRA’S ALGORITHM

AIM:
Write a Python program for single source shortest path using Dijiktra’s Algorithm.

ALGORITHM:
1. Create a class named `Graph` with the following methods:
- `__init__(self, vertices)`: Initializes the graph object with the number of vertices and creates an empty
adjacency matrix.
- `printSolution(self, dist)`: Prints the vertex and its distance from the source.
- `minDistance(self, dist, sptSet)`: Finds the vertex with the minimum distance value from the set of
vertices not yet included in the shortest path tree.
- `dijkstra(self, src)`: Implements Dijkstra's algorithm to find the shortest paths from the source to all
other vertices.
2. In the `dijkstra` method:
- Create a distance list `dist` and initialize it with a large value (1e7) for all vertices except the source
vertex, which is set to 0.
- Create a shortest path tree set `sptSet` and initialize all vertices as `False`.
- Iterate `cout` over the range of vertices.
- Find the vertex `u` with the minimum distance value from the set of vertices not yet processed by
calling the `minDistance` method.
- Mark `u` as visited by setting `sptSet[u]` to `True`.
- Update the distances of the adjacent vertices of `u` if the current distance is greater than the new
distance through `u`.
- Finally, call the `printSolution` method to print the shortest distances from the source vertex.
3. Create an instance `g` of the `Graph` class with 9 vertices.
4. Set the adjacency matrix `g.graph` to the provided graph representation.
5. Call the `dijkstra` method on `g` with the source vertex index (0 in this case).

PROGRAM:

# Python program for Dijkstra's single


# source shortest path algorithm. The program is
# for adjacency matrix representation of the graph
class Graph():

def __init__(self, vertices):


self.V = vertices
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]

def printSolution(self, dist):


print("Vertex \t Distance from Source")
for node in range(self.V):
print(node, "\t\t", dist[node])
# A utility function to find the vertex with
# minimum distance value, from the set of vertices
# not yet included in shortest path tree
def minDistance(self, dist, sptSet):

# Initialize minimum distance for next node


min = 1e7

# Search not nearest vertex not in the


# shortest path tree
for v in range(self.V):
if dist[v] < min and sptSet[v] == False:
min = dist[v]
min_index = v

return min_index

# Function that implements Dijkstra's single source


# shortest path algorithm for a graph represented
# using adjacency matrix representation
def dijkstra(self, src):

dist = [1e7] * self.V


dist[src] = 0
sptSet = [False] * self.V

for cout in range(self.V):

# Pick the minimum distance vertex from


# the set of vertices not yet processed.
# u is always equal to src in first iteration
u = self.minDistance(dist, sptSet)

# Put the minimum distance vertex in the


# shortest path tree
sptSet[u] = True

# Update dist value of the adjacent vertices


# of the picked vertex only if the current
# distance is greater than new distance and
# the vertex in not in the shortest path tree
for v in range(self.V):
if (self.graph[u][v] > 0 and sptSet[v] == False and
dist[v] > dist[u] + self.graph[u][v]):
dist[v] = dist[u] + self.graph[u][v]

self.printSolution(dist)

# Driver program
g = Graph(9)
g.graph = [[0, 4, 0, 0, 0, 0, 0, 8, 0],[4, 0, 8, 0, 0, 0, 0, 11, 0], [0, 8, 0, 7, 0, 4, 0, 0, 2],[0, 0, 7, 0, 9, 14, 0, 0,
0],[0, 0, 0, 9, 0, 10, 0, 0, 0],[0, 0, 4, 14, 10, 0, 2, 0, 0],[0, 0, 0, 0, 0, 2, 0, 1, 6],[8, 11, 0, 0, 0, 0, 1, 0, 7],[0, 0,
2, 0, 0, 0, 6, 7, 0]]
g.dijkstra(0)

OUTPUT:

Vertex Distance from Source


0 0
1 4
2 12
3 19
4 21
5 11
6 9
7 8
8 14

RESULT:
Thus, the Python program to implement single source shortest path using Dijikstra’s
Algorithm has been executed successfully.
EX: NO: 14 A IMPLEMENTATION OF MINIMUM SPANNING TREE

DATE: Prim’s algorithm

AIM:
Write a Python program to find minimum spanning tree from a given graph using Prim’s algorithm.

ALGORITHM:
1. Create a class `Graph` with a constructor that initializes the number of vertices (`V`) and an empty
adjacency matrix (`graph`).
2. Implement the `printMST` method to print the constructed MST stored in the `parent` array. Iterate over
the vertices (excluding the first one) and print the parent-child relationship along with the weight of the
edge.
3. Implement the `minKey` method to find the vertex with the minimum distance value, from the set of
vertices not yet included in the MST (`mstSet`). Initialize `min` as a large value (`sys.maxsize`), iterate
over all vertices, and update `min` and `min_index` if a smaller key value is found.
4. Implement the `primMST` method to construct and print the MST. Initialize the `key` array with large
values, `parent` array with `None`, and `mstSet` array with `False`. Set the key value of the first vertex to 0
to ensure it is picked first. Set the parent of the first vertex as -1.
5. Iterate `self.V` times to select `self.V` vertices for the MST. In each iteration, find the vertex (`u`) with
the minimum key value that is not yet included in the MST using the `minKey` method. Set `mstSet[u]` to
`True` to mark it as included in the MST.
6. Update the key values of the adjacent vertices of `u` if the current distance is greater than the new
distance (`self.graph[u][v]`) and the vertex is not already included in the MST. Iterate over all vertices (`v`)
and if the edge between `u` and `v` exists (`self.graph[u][v] > 0`), update `key[v]` and `parent[v]` values.
7. Finally, call the `printMST` method with the `parent` array to print the MST.
8. Create an instance of the `Graph` class with 5 vertices. Assign the adjacency matrix representation of the
graph to the `graph` attribute.
9. Call the `primMST` method to find and print the MST.

PROGRAM:
import sys

class Graph:
def __init__(self, vertices):
self.V = vertices
self.graph = [[0 for column in range(vertices)]
for row in range(vertices)]

def printMST(self, parent):


print("Edge \tWeight")
for i in range(1, self.V):
print(parent[i], "-", i, "\t", self.graph[i][parent[i]])

def minKey(self, key, mstSet):


min = sys.maxsize
for v in range(self.V):
if key[v] < min and mstSet[v] == False:
min = key[v]
min_index = v
return min_index

def primMST(self):
key = [sys.maxsize] * self.V
parent = [None] * self.V
key[0] = 0
mstSet = [False] * self.V
parent[0] = -1

for cout in range(self.V):


u = self.minKey(key, mstSet)
mstSet[u] = True

for v in range(self.V):
if (
self.graph[u][v] > 0
and mstSet[v] == False
and key[v] > self.graph[u][v]
):
key[v] = self.graph[u][v]
parent[v] = u

self.printMST(parent)

g = Graph(5)
g.graph = [
[0, 2, 0, 6, 0],
[2, 0, 3, 8, 5],
[0, 3, 0, 0, 7],
[6, 8, 0, 0, 9],
[0, 5, 7, 9, 0]
]

g.primMST()
Output:

Edge Weight
0-1 2
1-2 3
0-3 6
1-4 5

RESULT:
Thus, the Python program to implement minimum spanning tree from a given graph using
Prim’s algorithm has been executed successfully.
EX: NO: 14 B
IMPLEMENTATION OF MINIMUM SPANNING TREE
DATE:
Krushkal’s algorithm

Aim:
Write a Python program to find minimum spanning tree from a given graph using Krushkal
algorithm.

ALGORITHM:
1. Initialize an empty list called `result` to store the edges of the MST.
2. Sort the graph's edges in non-decreasing order of their weights.
3. Initialize two empty lists called `parent` and `rank` to track the parent and rank of each vertex.
4. Create subsets with single elements for each vertex. Set the initial parent of each vertex to itself and rank
to 0.
5. Iterate through each edge in the sorted graph:
- Get the source vertex (u), destination vertex (v), and weight (w) of the current edge.
- Find the root vertices (x and y) of the subsets to which u and v belong using the `find` function.
- If x and y are not the same (i.e., including this edge doesn't cause a cycle), add the edge to the `result`
list and merge the subsets using the `union` function.
6. Calculate the total weight of the MST by summing the weights of the edges in the `result` list.
7. Print the edges and their weights in the constructed MST.
8. Print the minimum spanning tree's total weight.

PROGRAM:
from collections import defaultdict

class Graph:

def __init__(self, vertices):


self.V = vertices # No. of vertices
self.graph = [] # default dictionary
# to store graph

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


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

# A utility function to find set of an element i


# (uses path compression technique)
def find(self, parent, i):
if parent[i] == i:
return i
return self.find(parent, parent[i])

# A function that does union of two sets of x and y


# (uses union by rank)
def union(self, parent, rank, x, y):
xroot = self.find(parent, x)
yroot = self.find(parent, y)

# Attach smaller rank tree under root of


# high rank tree (Union by Rank)
if rank[xroot] < rank[yroot]:
parent[xroot] = yroot
elif rank[xroot] > rank[yroot]:
parent[yroot] = xroot

# If ranks are same, then make one as root


# and increment its rank by one
else:
parent[yroot] = xroot
rank[xroot] += 1

# The main function to construct MST using Kruskal's


# algorithm
def KruskalMST(self):

result = [] # This will store the resultant MST

# An index variable, used for sorted edges


i=0

# An index variable, used for result[]


e=0

# Step 1: Sort all the edges in


# non-decreasing order of their
# weight. If we are not allowed to change the
# given graph, we can create a copy of graph
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 and increment


# the index for next iteration
u, v, w = self.graph[i]
i=i+1
x = self.find(parent, u)
y = self.find(parent, v)
# If including this edge doesn't
# cause cycle, include it in result
# and increment the indexof result
# for next edge
if x != y:
e=e+1
result.append([u, v, w])
self.union(parent, rank, x, y)
# Else discard the edge

minimumCost = 0
print ("Edges in the constructed MST")
for u, v, weight in result:
minimumCost += weight
print("%d -- %d == %d" % (u, v, weight))
print("Minimum Spanning Tree" , minimumCost)

# Driver code
g = Graph(4)
g.addEdge(0, 1, 10)
g.addEdge(0, 2, 6)
g.addEdge(0, 3, 5)
g.addEdge(1, 3, 15)
g.addEdge(2, 3, 4)

# Function call
g.KruskalMST()

OUTPUT:

Edges in the constructed MST


2 -- 3 == 4
0 -- 3 == 5
0 -- 1 == 10
Minimum Spanning Tree 19

RESULT:
Thus, the Python program to implement minimum spanning tree from a given graph using Krushkal
algorithm has been executed successfully.

You might also like