You are on page 1of 77

EX.

NO: 01
LINEAR SEARCH
DATE :

AIM:
To write a python program for linear search to calculate its
time complexity.

ALGORITHM:

STEP1: Start
STEP2: Start at the beginning of the list or array to be searched.
STEP3: Set a variable i to 0, which represents the index of the current
element being examined.
STEP4: If the current element equals the value being searched for,
return the index i.
STEP5: If the end of the list has been reached without finding the value,
return a message indicating that the value was not foundIf the value has
not been found, increment i by 1 and go to step 3.
STEP6: Repeat steps 3 to 5 until the value is found or until the end of the
list is reached.
STEP7: Stop
PROGRAM:
import time
import random
import matplotlib.pyplot as plt
def linear_Search(list1, n, key):
for i in range(0, n):
if (list1[i] == key):
return i
return -1
x1=list1 = list(range(1000001))
x2=list2=list(range(10000))
x3=list3 = list(range(10000001))
print("\nLenght of list 1 : ",len(list1))
print("\nLenght of list 1 : ",len(list2))
print("\nLenght of list 3 : ",len(list3))
key1 = 900000
key2 = 9999
key3 = 900000
n1 = len(list1)
n2 = len(list2)
n3=len(list3)
start1=time.time()
res1 = linear_Search(list1, n1, key1)
end1=time.time()
start2=time.time()
res2 = linear_Search(list2, n2, key2)
end2=time.time()
start3=time.time()
res3 = linear_Search(list3, n3, key3)
end3=time.time()
print("\n\n\tList 1")
if(res1 == -1):
print("Element not found")
else:
print("Element found at index: ", res1)
t1=end1-start1
print("\nTotal time : ",t1)
print("\n\n\tList 2")
if(res2 == -1):
print("Element not found")
else:
print("Element found at index: ", res2)
t2=end2-start2
print("\nTotal time : ",t2)
print("\n\n\tList 3")
if(res3 == -1):
print("Element not found")
else:
print("Element found at index: ", res3)
t3=end3-start3
print("\nTotal time : ",t3)
print("\n\nPlotting")
plt.plot([t1,t2,t3])
plt.show()

OUTPUT:
Length of list 1 : 1000001
Length of list 2 : 10000
Length of list 3 : 10000001
List 1
Element found at index: 900000
Total time : 0.14290952682495117
List 2
Element found at index: 9999
Total time : 0.0010023117065429688
List 3
Element found at index: 900000
Total time : 0.1069328784942627

RESULT:
Thus the python program for linear search to calculate its time
complexity was written and verified successfully.
EX.NO: 2
BINARY SEARCH
DATE :

AIM:

To write a python program to perform and to find time complexity for the binary search.

ALGORITHM:

STEP 1: Start

STEP 2: Initialize two variables low and high as the first and last indices of the list, respectively.

STEP 3: While low is less than or equal to high, do the following:

a. Calculate the midpoint index mid as (low + high) //

2. b. If the element at index mid is equal to x, return mid. c. If the element at index mid is greater than x, set
high to mid - 1. d. If the element at index mid is less than x, set low to mid + 1.

STEP 4: If x is not found in arr, return -1.

STEP 5: Initialize two empty lists x and y to store the time taken and n values, respectively.

STEP 6: For each value of n from 1000 to 9000 (inclusive) in steps of 1000, do the following:

a. Generate a list arr of n random integers between 1 and n*2.

b. Set the key to be the index of the second-to-last element in arr.

c. Print arr.

d. Start a timer.

e. Call the binary_search function with arguments arr, 0, len(arr)-1, and key, and store the result in res.

f. If res is -1, print "Element not found". Otherwise, print "Element found at index: " followed by res.

g. Stop the timer and compute the time taken as the difference between the end time and the start time,
multiplied by 1000 to convert to milliseconds.

h. Append the time taken to the list x and the value of n to the list y.

STEP 7: Plot the values in x versus the values in y using matplotlib.

STEP 8: Stop.
PROGRAM:

import time
import random
import matplotlib.pyplot as plt

def binary_search(arr, low, high, x):


if high >= low:
mid = (high + low) // 2
if arr[mid] == x:
return mid
elif arr[mid] > x:
return binary_search(arr, low, mid - 1, x)
else:
return binary_search(arr, mid + 1, high, x)
else:
return -1

x=[]
y=[]
for n in range(1, 10000):
if n % 1000 == 0:
arr= [random.randint(1,n*2) for _ in range(n)]
key=len(arr)-6
print(arr)
start=time.time()
res = binary_search(arr, 0, len(arr) - 1, key)
if res == -1:
print("Element not found")
else:
print("Element found at index: ", res)
end=time.time()
t=(end-start)*1000
print(t)
x.append(t)
y.append(n)
plt.plot(x,y)
plt.title("Binary Search Time Complexity")
plt.xlabel("Time Taken (ms)")
plt.ylabel("n Values")
plt.show()
OUTPUT:

Element not found


0.0

RESULT:
Thus the python program to perform and find time complexity for the binary
search was written and verified successfully.
EX.NO:
PATTERN SEARCH
DATE

AIM:
To write a python program to find the pattern search for the given substring.

ALGORITHM:
STEP 1: Start
STEP 2: Define the text string to be searched and the pattern string to be matched.
STEP 3: Get the length of the pattern string.
STEP 4 : Initialize a variable i to 0, which represents the current index position in
the text string.
STEP 5: Initialize a variable j to 0, which represents the current index position in
the pattern string.
STEP 6: While i is less than the length of the text string, do the following:
a. If the current character in the text string matches the current character in the
pattern string, increment both i and j.
b. If j is equal to the length of the pattern string, then the pattern has been found
at index i - j in the text string. Return this index.
c. If the current character in the text string does not match the current character
in the pattern string, increment i by 1 and set j back to 0.
STEP 7: If the pattern was not found in the text string, return a message indicating
that the pattern was not found.
STEP 8: Stop.
PROGRAM:
import time

import matplotlib.pyplot as plt

test_str = "Nory was a Catholic because her mother was a Catholic, and Nory’s mother was a Catholic
because her father was a Catholic, and her father was a Catholic because his mother was a Catholic, or had
been"

test_sub = input('Enter the Pattern SubString: ')

# printing original string

print("The original string is : " + test_str)

# printing substring

print("\nThe substring to find : " + test_sub)

# using list comprehension + startswith()

# All occurrences of substring in string

if test_sub in test_str:

start=time.time()

res = [i for i in range(len(test_str)) if test_str.startswith(test_sub, i)]

end=time.time()

t=end-start

# printing result

print("The start indices of the substrings are : " + str(res))

n=len(list(res))

print("\ntotal time taken",t)

print("\ntotal counts of substring",n)

plt.plot([n,t])
plt.show()

else:

print ("\n The substring is not found")

OUTPUT:
Enter the Pattern SubString: was

The original string is: Nory was a Catholic because her mother was a Catholic, and
Nory’s mother was a Catholic because her father was a Catholic, and her father w
as a Catholic because his mother was a Catholic, or had been

The substring to find : was

The start indices of the substrings are : [5, 39, 73, 107, 138, 172]

total time taken 0.0010020732879638672

total counts of substring 6


RESULT:
Thus the python program to find the pattern search for the given substring
was written and verified successfully.
EX.NO: 4A
INSERTION SORT
DATE :

AIM:
To write a python program to perform and find time complexity for insertion
sort.

ALGORITHM:

STEP1: Start
STEP 2: Define an unsorted array of n elements.
STEP 3: Begin a loop that will iterate over each element in the unsorted array,
starting with the second element (i.e., index 1).
STEP 4: Within the loop, store the current element in a variable called "key".
STEP 5: Initialize a variable called "j" to be the index of the previous element (i.e.,
index of the current element minus 1).
STEP 6: While j is greater than or equal to zero and the element at index j is
greater than the key:
a. Shift the element at index j one position to the right (i.e., set the value at index
j+1 to be the same as the value at index j).
b. Decrement j by 1.
STEP 7: After the while loop is complete, set the value at index j+1 to be the key
value.
STEP 8: Continue the loop over each remaining element in the unsorted array until
all elements have been inserted into their proper positions.
STEP 9 : The array is now sorted in ascending order.
STEP 10: Stop.
PROGRAM:

import time
def insertionSort(arr):
n=len(arr)
if len(arr) <= 1:
return
for i in range(1, n):
key = arr[i]
j = i-1
while j >=0 and key < arr[j] :
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
X=[]
Y=[]
for n in range(1, 301):

if n % 50 == 0:
arr= [random.randint(1,n*2) for _ in range(n)]
random.shuffle(arr)
print(arr)
start=time.time()
insertionSort(arr)
print(arr)
end=time.time()
t=(end-start)*1000
print(t)
X.append(t)
Y.append(n)
print(X)
print(Y)

plt.plot(X,Y)
plt.title("INSERTION SORT TIME COMPLEXITY")
plt.xlabel("Time Taken")
plt.ylabel("N values")
plt.show()

OUTPUT:
10.996580123901367

[0.9992122650146484, 2.0020008087158203, 2.9964447021484375, 6.994962692260742, 5.9


95035171508789, 10.996580123901367]

[50, 100, 150, 200, 250, 300]


RESULT:
Thus the python program to perform and find the time complexity for insertion sort was
written and verified successfully.
EX.NO: 4B
HEAP SORT
DATE :

AIM:
To write a python program to perform and find the time complexity for heap sort.

ALGORITHM:

STEP 1: Start
STEP 2 : Define an unsorted array of n elements.
STEP 3: Build a max-heap from the unsorted array.
STEP 4: Swap the first element (which is the largest element in the max-heap)
with the last element in the unsorted array.
STEP 5: Decrease the heap size by 1 to exclude the swapped element from future
heap operations.
STEP 6: Perform a heapify operation on the new root element (which was
previously the last element of the unsorted array).
STEP 7: Repeat steps 3-5 until the entire array is sorted.
STEP 8: The array is now sorted in ascending order.
STEP 9: Stop.
PROGRAM:
def heap_sort(arr):
n = len(arr)
# Build a max-heap
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
# Extract elements one by one
for i in range(n - 1, 0, -1):
arr[i], arr[0] = arr[0], arr[i] # swap
heapify(arr, i, 0)
def heapify(arr, n, i):
largest = i # Initialize largest as root
l = 2 * i + 1 # left = 2*i + 1
r = 2 * i + 2 # right = 2*i + 2
# If left child is larger than root
if l < n and arr[l] > arr[largest]:
largest = l
# If right child is larger than largest so far
if r < n and arr[r] > arr[largest]:
largest = r
# If largest is not root
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i
heapify(arr, n, largest)
x=[]
y=[]
for n in range(1, 301):
if n % 50 == 0:
arr= [random.randint(1,n*2) for _ in range(n)]
random.shuffle(arr)
print(arr)
start=time.time()
heap_sort(arr)
print(arr)
end=time.time()
t=(end-start)*1000
print(t)
x.append(t)
y.append(n)
plt.plot(x,y)
plt.title("HEAP SORT TIME COMPLEXITY")
plt.xlabel("Time Taken")
plt.ylabel("N values")
plt.show()
OUTPUT:

RESULT:

Thus the python program to perform and find the time complexity for heap sort was
written and verified successfully.
EX.NO: 5
BREADTH FIRST SEARCH
DATE :

AIM:
To develop a python program to implement the graph algorithns using BFS.

ALGORITHM:
Step 1: Start the program.
Step 2: Read the adjacency matrix for the graph.
Step 3:Read the starting vertex.
Step 4:Start traversal from the vertex,look for all adjacent vertices of it.
Step 5: If we don’t mark visited vertices,then it will be processed again and again
and it
will become a non-terminating process.
Step 6: Print the visited vertices.
Step 7: Stop the program.
PROGRAM:
from collections import defaultdict
# This class represents a directed graph using adjacency list representation
class Graph:
# Constructor
def __init__(self):
# default dictionary to store graph
self.graph = defaultdict(list)
# function to add an edge to graph
def addEdge(self,u,v):
self.graph[u].append(v)
# Function to print a BFS of graph
def BFS(self, s):
# Mark all the vertices as not visited
visited = [False] * (len(self.graph))
# Create a queue for BFS
queue = []
# Mark the source node as
# visited and enqueue it
queue.append(s)
visited[s] = True
while queue:
# Dequeue a vertex from
# queue and print it
s = queue.pop(0)
print (s )
# Get all adjacent vertices of the
# dequeued vertex s. If a adjacent
# has not been visited, then mark it
# visited and enqueue it
for i in self.graph[s]:
if visited[i] == False:
queue.append(i)
visited[i] = True
# Create a graph given in the above diagram
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(3)
OUTPUT:

FOLLOWING IS BREADTH FIRST SEARCH

( STARTING FROM VERTEX 2)

RESULT:
Thus the python program to implement Breadth First Search was written
and verified successfully.
EX.NO: 6
DEPTH FIRST SEARCH
DATE :

AIM:
To write a python program to implement graph traversal using depth first
search.

ALGORITHM:
STEP 1: Start the program.
STEP 2: Read the adjacency matrix for the graph.
STEP 3:Read the starting vertex.
STEP 4:Start traversal from the vertex,look for all adjacent vertices of it.
STEP 5: If we don’t mark visited vertices,then it will be processed again and
again and it
will become a non-terminating process.
STEP 6: Print the visited vertices.
STEP 7: Stop the program.
PROGRAM:
from collections import defaultdict
# This class represents a directed graph using adjacency
# list representation
class Graph:
# Constructor
def __init__(self):
# default dictionary to store graph
self.graph = defaultdict(list)
# function to add an edge to graph
def addEdge(self,u,v):
self.graph[u].append(v)
# A function used by DFS
def DFSUtil(self, v, visited):
# Mark the current node as visited and print it
visited[v]= True
print( v)
# Recur for all the vertices adjacent to
# this vertex
for i in self.graph[v]:
if visited[i] == False:
self.DFSUtil(i, visited)
# The function to do DFS traversal. It uses
# recursive DFSUtil()
def DFS(self):
V = len(self.graph) #total vertices
# Mark all the vertices as not visited
visited =[False]*(V)
# Call the recursive helper function to print
# DFS traversal starting from all vertices one
# by one
for i in range(V):
if visited[i] == False:
self.DFSUtil(i, 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 Depth First Traversal”)
g.DFS()
OUTPUT:

FOLLOWING IS DEPTH FIRST SEARCH

0 1 2 3

RESULT:
Thus the python program to implement graph traversal using depth
first search was written and verified successfully.
EX.NO: 7
DIJKSTRA’S ALGORITHM
DATE :

AIM:
To develop a program to find the shortest path to other vertices using
dijkstra’s algorithm.

ALGORITHM:
STEP 1: Start
STEP 2: Define the graph and a source vertex s.
STEP 3: Initialize a distance array dist[] where dist[v] represents the shortest distance from the
source vertex s to vertex v. Set dist[s] to 0 and all other distances to infinity.
STEP 4: Initialize a set S containing all vertices in the graph.
STEP 5: While S is not empty, do the following:
a. Find the vertex u in S with the smallest dist[u] value.
b. Remove u from S.
c. For each neighbor v of u, do the following:
i. If v is in S, calculate a new tentative distance from s to v by adding the weight of the edge
from u to v to dist[u].
ii. If the new tentative distance is smaller than the current dist[v] value, update dist[v] to the
new distance.
STEP 6: The dist[] array now contains the shortest path distances from s to all other vertices in
the graph.
STEP 7: Stop.
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])
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
def dijkstra(self, src):
dist = [1e7] * self.V
dist[src] = 0
sptSet = [False] * self.V
for cout in range(self.V):
u = self.minDistance(dist, sptSet)
sptSet[u] = True
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)
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 dijkstra’s algorithm was
written and verified successfully.
EX.NO: 8
PRIM’S ALGORITHM
DATE :

AIM:
To find the minimum cost spanning tree of a given undirected graph using prim’s
algorithm.
ALGORITHM:
STEP 1: Determine an arbitrary vertex as the starting vertex of the MST.
STEP 2: Follow step3 to 5 until there are vertices that are not included in
the MST.
STEP 3: Find edges connecting any tree vertex with the MST.
STEP 4: Find the minimum among these edges.
STEP 5: Add the chosen edge to the MST if it does not form any cycle.
STEP 6: Return the MST & Exit.
STEP 7: Stop
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 printMST(Self):
key =[sys.maxsize] * Self.V
parent =[None] * Self.V
key [0]=0
mstset =[False] * Self.V
parent [0]= -1
for count 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)
If __ name __==’__ main __’
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.printMST()
OUTPUT:
Edge Weight
0-1 2
1-2 3
0-3 6
1-4 5

RESULT:
Thus the program to find the minimum cost spanning tree of a given
undirected graph using prim’s algorithm was written and verified successfully.
EX.NO: 9
FLOYD’S ALORITHM
DATE :

AIM:
To implement Floyd’s Algorithm for the All-Pairs-Shortest-Paths problem
using python.

ALGORITHM:
STEP1: Start
STEP 2: Initialize the shortest paths between any 2 vertices with Infinity.
STEP 3: Find all pair shortest paths that use 0 intermediate vertices, then find the
shortest paths that use 1 intermediate vertex and so on until using all N vertices as
intermediate nodes.
STEP 4: Minimize the shortest paths between any 2 pairs in the previous
operation.
STEP 5: For any 2 vertices (i,j) , one should actually minimize the distances
between this pair using the first K nodes, so the shortest path will be:
min(dist[i][k]+dist[k][j],dist[i][j]).
dist[i][k] represents the shortest path that only uses the first K vertices, dist[k][j]
represents the shortest path between the pair k,j. As the shortest path will be a
concatenation of the shortest path from i to k, then from k to j.
STEP 6: Stop
PROGRAM:
# The number of vertices
nV = 4
INF = 999

def floyd(G):
distance = list(map(lambda i: list(map(lambda j: j, i)), G))

# Adding vertices individually


for k in range(nV):
for i in range(nV):
for j in range(nV):
distance[i][j] = min(distance[i][j], distance[i][k] + distance[k][j])
print_solution(distance)

# Printing the solution


def print_solution(distance):
for i in range(nV):
for j in range(nV):
if(distance[i][j] == INF):
print("INF" )
else:
print(distance[i][j] )
print(" ")

G = [[0, 3, INF, 5],


[2, 0, INF, 4],
[INF, 1, 0, INF],
[INF, INF, 2, 0]]

floyd(G)

OUTPUT:
0 2 3 5
3 0 1 3
7 6 0 2
5 4 5 0
RESULT:
Thus the python program to implement Floyd’s algorithm for all-pair-
shortest-paths problem was written and verified successfully.
EX.NO: 10
WARSHALL’S ALGORITHM
DATE :

AIM:
To find compute the transitive closure of a given directed graph using
warshall’s algorithm.

ALGORITHM:
STEP 1: create a matrix to represent the graph
STEP 2: Initialize a transitive closure matrix with the same dimensions as the
graph matrix and set all Values to 0.
STEP 3: Use nested for loops to iterate over every pair of node in the graph.
STEP 4: If there is a directed edge between the nodes is set the corresponding
cell in the transitive Closure matrix to 1.
STEP 5: For each pair of node(I,j) iterate over everyy node IC in the graph,if
there is a path from node I to node k and a path from node k to node j.
STEP 6: Repeat Step5 until no more changes are made to the transitive closure
matrix.The finalTransitive closure matrix represents the transitive closure of the
original graph.
PROGRAM:
from collections import defaultdict
#Class to represent a graph
class Graph:
def _init_(self, vertices):
self.V = vertices
def printSolution(self, reach):
print ("Following matrix transitive closure of the given graph ")
for i in range(self.V):
for j in range(self.V):
if (i == j):
print ("%7d\t" % (1))
else:
print ("%7d\t" %(reach[i][j]))
print(" ")
def transitiveClosure(self,graph):
reach =[i[:] for i in graph]
for k in range(self.V):
for i in range(self.V) :
for j in range(self.V):
reach[i][j] = reach[i][j] or (reach[i][k] and reach[k][j])
self.printSolution(reach)
g= Graph(4)
graph = [[1, 1, 0, 1],
[0, 1, 1, 0],
[0, 0, 1, 1],
[0, 0, 0, 1]]
g.transitiveClosure(graph)

OUTPUT:
1 0
1 0
0 1
1 1
0 0
1 0
RESULT:
Thus the program for warshall algorithm was written and executed
successfully.
EX.NO: 11 MAXIMUM AND MINIMUM
DATE : NUMBER

AIM:

To write a python program for minimum and maximum elements in a given list of n
numbers using divide and conquer algorithm.

ALGORITHM:
STEP 1: Start
STEP 2: Define a function called find_min_and_max that takes in a list of numbers, a starting
index start, and an ending index end.
STEP 3: If sublist contains only one element, return that element as both minimum and
maximum values.
STEP 4: If sublist contains two elements, compare them to determine minimum and maximum
values, and return them.
STEP 5: If sublist contains more than two elements, divide the sublist into two equal parts.
STEP 6: Recursively call find_min_and_max on the left half of the sublist, assign returned
minimum and maximum values to left_min and left_max.
STEP 7: Recursively call find_min_and_max on the right half of the sublist, assign returned
minimum and maximum values to right_min and right_max
. STEP 8: Return minimum of left_min and right_min as minimum value of entire sublist, and
maximum of left_max and right_max as maximum value of entire sublist.
STEP 9: Call find_min_and_max function on entire list with start=0 and end=n-1.
STEP 10 : Output minimum and maximum values returned by the function.
STEP 11: Stop
PROGRAM:
import sys
# Divide and conquer solution to find the minimum and maximum number in a list
def findMinAndMax(nums, left, right, min=sys.maxsize, max=-sys.maxsize):
# if the list contains only one element
if left == right: # common comparison
if min > nums[right]: # comparison 1
min = nums[right]
if max < nums[left]: # comparison 2
max = nums[left]
return min, max
# if the list contains only two elements
if right - left == 1: # common comparison
if nums[left] < nums[right]: # comparison 1
if min > nums[left]: # comparison 2
min = nums[left]
if max < nums[right]: # comparison 3
max = nums[right]
else:
if min > nums[right]: # comparison 2
min = nums[right]
if max < nums[left]: # comparison 3
max = nums[left]
return min, max
# find the middle element
mid = (left + right) // 2
# recur for the left sublist
min, max = findMinAndMax(nums, left, mid, min, max)
# recur for the right sublist
min, max = findMinAndMax(nums, mid + 1, right, min, max)
return min, max
if _name_ == '_main_':
nums = [7, 2, 9, 3, 1, 6, 7, 8, 4]
# initialize the minimum element by INFINITY and the
# maximum element by -INFINITY
(min, max) = findMinAndMax(nums, 0, len(nums) - 1)
print("The minimum element in the list is", min)
print("The maximum element in the list is", max)

OUTPUT:
THE MINIMMUM ELEMENT IN THE LIST IS : 1
THE MAXIMUM ELEMENT IN THE LIST IS: 10
RESULT:
Thus the python program for minimum and maximum elements in a given list of
n numbers using divide and conquer algorithm was written and verified successfully.
EX.NO: 12 a
MERGE SORT
DATE :

AIM:
To write a python program to sort the given array using merge sort
algorithm.

ALGORITHM:
STEP 1: Start the program.
STEP 2: Read the given list.
STEP 3: If the list is empty .Return the given list was empty.
STEP 4: Otherwise divide the given list until by single element.
STEP 5: Sort the each element and merge the elements.
STEP 6: Print the sorted array.
STEP 7: Calculate the time complexity.
STEP 8: Plot the graph with values and time taken.
STEP 9: Print the output.
STEP 10: Stop the program.
PROGRAM:
import time

import random
import matplotlib.pyplot as plt

def merge(arr, l, m, r):

n1 = m - l + 1

n2 = r - m

# create temp arrays


L = [0] * (n1)

R = [0] * (n2)

# Copy data to temp arrays L[] and R[]

for i in range(0, n1):


L[i] = arr[l + i]

for j in range(0, n2):

R[j] = arr[m + 1 + j]

# Merge the temp arrays back into arr[l..r]

i = 0 # Initial index of first subarray

j = 0 # Initial index of second subarray

k = l # Initial index of merged subarray

while i < n1 and j < n2:

if L[i] <= R[j]:


arr[k] = L[i]

i += 1
else:

arr[k] = R[j]

j += 1

k += 1

while i < n1:

arr[k] = L[i]

i += 1
k += 1

# Copy the remaining elements of R[], if there

# are any

while j < n2:


arr[k] = R[j]

j += 1

k += 1

def mergeSort(arr, l, r):

if l < r:
m = l+(r-l)//2

mergeSort(arr, l, m)

mergeSort(arr, m+1, r)

merge(arr, l, m, r)

X=[]

Y=[]

for n in range(1, 3001):

if n % 500 == 0:
arr= [random.randint(1,n*2) for _ in range(n)]

N=len(arr)

random.shuffle(arr)

print(arr)

start=time.time()

mergeSort(arr, 0, N-1)

print("\nSorted array is")


for i in range(n):

print("%d" % arr[i],end=" ")

end=time.time()

t=(end-start)*1000
print("\n TIME COMLEXITY",t)

X.append(t)

Y.append(n)

print(X)

print(Y)
plt.plot(X,Y)

plt.title("MERGE SORT TIME COMPLEXITY")

plt.xlabel("Time Taken")

plt.ylabel("N values")

plt.show()
OUTPUT:

TIME COMLEXITY 16.800642013549805

RESULT:
Thus the python program to the given merge sort was written and verified
successfully .
EX.NO: 12 b
QUICK SORT
DATE :

AIM:
To write a python program to sort the elements using quick sort.

ALGORITHM:
STEP 1: Start the program.
STEP 2: Import necessary libraries such as time, random, and matplotlib.pyplot.

STEP 3: Define the partition function that takes an array, low and high indices as
input.

STEP 4: Choose the rightmost element as the pivot.

STEP 5: Initialize a pointer i to low-1.

STEP 6: Traverse through all elements in the array and compare each element
with the pivot.

STEP 7: If an element smaller than the pivot is found, swap it with the greater
element pointed by i, and increment i.

STEP 8: Swap the pivot element with the greater element specified by i+1.

STEP 9: Return the position from where the partition is done.

STEP 10: Define the quickSort function that takes an array, low, and high indices
as input.

STEP 11: If low is less than high, find the pivot element such that elements
smaller than the pivot are on the left and elements.
STEP 12: Stop the program.
PROGRAM:
import time
import random
import matplotlib.pyplot as plt
def partition(array, low, high):
pivot = array[high]
i = low - 1
for j in range(low, high):
if array[j] <= pivot:
i=i+1
(array[i], array[j]) = (array[j], array[i])
(array[i + 1], array[high]) = (array[high], array[i + 1])
return i + 1
def quickSort(array, low, high):
if low < high:
pi = partition(array, low, high)
quickSort(array, low, pi – 1)
quickSort(array, pi + 1, high)
X=[]
Y=[]
for n in range(1, 3001):
if n % 500 == 0:
arr= [random.randint(1,n*2) for _ in range(n)]
N=len(arr)
random.shuffle(arr)
print(arr)
start=time.time()
quickSort(arr, 0, N-1)
print("\nSorted array is")
for i in range(n):
print("%d" % arr[i],end=" ")
end=time.time()
t=(end-start)*1000
print("\n TIME COMLEXITY",t)
X.append(t)
Y.append(n)
print(X)
print(Y)
plt.plot(X,Y)
plt.title(" QUICK SORT TIME COMPLEXITY")
plt.xlabel("Time Taken")
plt.ylabel("N values")
plt.show()
OUTPUT:

RESULT:

Thus the python program to sort the given quick sort was written and verified
successfully.
EX.NO: 13
STATE SPACE SEARCH
DATE : ALGORITHM

AIM:
To write a python program for implement a state space search algorithm.

ALGORITHM:
STEP 1: Start the program.
STEP 2:Define a function named solveNQUtil that takes an integer parameter “N”
representing the size of chess board.
STEP 3:Create an empty N*N chessboard represented as a 2D array called board.
STEP 4:Define a function called “isSafe” that takes three parameters row ,column & board
and returns a Boolean indicating whether or not it is safe to place a queen in the given row and
column.
STEP 5:In the safe function check if there is any other queen in the same row ,column or
diagonal it return false otherwise return true
STEP 6:In the “printSolution” function use a loop to iterate over all column in the current
row.
STEP 7:If the recursive call return false ,it backtrack by unmarking the current call on the
board and also trying the next column.
STEP 8:If “printSolution” function returns true by printing the solution otherwise print
“Solution does not exist”.
STEP 9:Stop the program.
PROGRAM:
global N
N=8
def printSolution(board):
for i in range(N):
for j in range(N):
print (board[i][j], end = " ")
print()
def isSafe(board, row, col):
for i in range(col):
if board[row][i] == 1:
return False
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 1:
return False
for i, j in zip(range(row, N, 1), range(col, -1, -1)):
if board[i][j] == 1:
return False
return True
def solveNQUtil(board, col):
if col >= N:
return True
for i in range(N):
if isSafe(board, i, col):
board[i][col] = 1
if solveNQUtil(board, col + 1) == True:
return True
board[i][col] = 0
return False
def solveNQ():
board = [ [0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]
]
if solveNQUtil(board, 0) == False:
print ("Solution does not exist")
return False
printSolution(board)
return True
solveNQ()
OUTPUT:

10000000
00000010
00001000
00000001
01000000
00010000
00000100
00100000

True

RESULT:

Thus the python code to implement state space search algorithm was written and
verified successfully.
EX.NO: 14
TRAVELLING SALESPERSON
DATE : PROBLEM

AIM:
To find the optimal solution for the Traveling Salesperson problem and then solve the
same problem instance using any approximation algorithm and determine the error in the
approximation.

ALGORITHM:
STEP 1: Start the program.

STEP 2: Start on an arbitrary vertex as current vertex.


STEP 3: Find out the shortest edge connecting current vertex and an unvisited vertex V.
STEP 4: Set current vertex to V.
STEP 5: Mark V as visited.
STEP 6: If all the vertices in domain are visited, then terminate.
STEP 7: Go to step 2.
STEP 8: The sequence of the visited vertices is the output of the algorithm.
STEP 9: Stop the program.
PROGRAM:
#include<stdio.h>
int a[10][10],n,visit[10];
int cost_opt=0,cost_apr=0;
int least_apr(int c);
int least_opt(int c);
void mincost_opt(int city)
{
int i,ncity;
visit[city]=1;
printf("%d-->",city);
ncity=least_opt(city);
if(ncity==999)
{
ncity=1;
printf("%d",ncity);
cost_opt+=a[city][ncity];
return;

}
mincost_opt(ncity);
}
void mincost_apr(int city)
{
int i,ncity;
visit[city]=1;
printf("%d-->",city);
ncity=least_apr(city);
if(ncity==999)
{
ncity=1;

printf("%d",ncity);
cost_apr+=a[city][ncity];
return;
}
mincost_apr(ncity);
}
int least_opt(int c)
{
int i,nc=999;

int min=999,kmin=999;
for(i=1;i<=n;i++)
{
if((a[c][i]!=0)&&(visit[i]==0))
if(a[c][i]<min)
{
min=a[i][1]+a[c][i];
kmin=a[c][i];
nc=i;
}
}
if(min!=999)
cost_opt+=kmin;
return nc;
}

int least_apr(int c)
{
int i,nc=999;
int min=999,kmin=999;
for(i=1;i<=n;i++)
{
if((a[c][i]!=0)&&(visit[i]==0))
if(a[c][i]<kmin)
{

min=a[i][1]+a[c][i];
kmin=a[c][i];
nc=i;
}
}
if(min!=999)
cost_apr+=kmin;
return nc;
}
void main()
{
int i,j;
printf("Enter No. of cities:\n");
scanf("%d",&n);

printf("Enter the cost matrix\n");


for(i=1;i<=n;i++)
{
printf("Enter elements of row:%d\n",i );
for(j=1;j<=n;j++)
scanf("%d",&a[i][j]);
visit[i]=0;
}
printf("The cost list is \n");

for(i=1;i<=n;i++)
{
printf("\n\n");
for(j=1;j<=n;j++)
printf("\t%d",a[i][j]);
}
printf("\n\n Optimal Solution :\n");
printf("\n The path is :\n");
mincost_opt(1);
printf("\n Minimum cost:");
printf("%d",cost_opt);
printf("\n\n Approximated Solution :\n");
for(i=1;i<=n;i++)
visit[i]=0;
printf("\n The path is :\n");

mincost_apr(1);
printf("\nMinimum cost:");
printf("%d",cost_apr);
printf("\n\nError in approximation is approximated solution/optimal solution=%f",
(float)cost_apr/cost_opt);
}

OUTPUT:

Enter No. of cities: 4


Enter the cost matrix
Enter elements of row:1 0136
Enter elements of row:2 1023
Enter elements of row:3 3201
Enter elements of row:4 6310
The cost list is
0 1 3 6
1 0 2 3
3 2 0 1
6 3 1 0
Optimal Solution :

The path is : 1-->2-->4-->3-->1


Minimum cost:8
Approximated Solution :
The path is : 1-->2-->3-->4-->1
Minimum cost:10
Error in approximation is approximated solution/optimal solution=1.250000

RESULT:
Thus to find the optimal solution for the Traveling Salesperson problem and then solve
the same problem instance using any approximation algorithm and determine the error in the
approximation was written and verified successfully.
EX.NO: 15 FINDING THE K TH
DATE : SMALLEST NUMBER

AIM:
To implement randomized algorithms for finding the kth smallest number
using Quick select.

ALGORITHM:
STEP 1: Start the program.
STEP 2: Select a random element from a array as a pivot.
STEP 3: Then partition to the array around the pivot, its help to all the smaller
element were placed before in the pivot and all greater element are placed after the
pivot.
STEP 4: then Check the position of the pivot. If it is the kth element then return it.
STEP 5: If it is the less than the kth element then repeat the process of the
subarray.
STEP 6: If it is the greater then the kth element then repeat the process of the left
subarray.
STEP 7: Stop the program.
PROGRAM:
import random
def kthSmallest(arr, l, r, k):
if (k > 0 and k <= r - l + 1):
pos = randomPartition(arr, l, r)
# If position is same as k
if (pos - l == k - 1):
return arr[pos]
if (pos - l > k - 1): # If position is more,
# recur for left subarray
return kthSmallest(arr, l, pos - 1, k)

# Else recur for right subarray


return kthSmallest(arr, pos + 1, r,
k - pos + l - 1)
# If k is more than the number of
# elements in the array
return 999999999999
def swap(arr, a, b):
temp = arr[a]
arr[a] = arr[b]
arr[b] = temp
def partition(arr, l, r):
x = arr[r]
i=l
for j in range(l, r):
if (arr[j] <= x):
swap(arr, i, j)
i += 1
swap(arr, i, r)
return i
def randomPartition(arr, l, r):
n=r-l+1
pivot = int(random.random() * n)
swap(arr, l + pivot, r)
return partition(arr, l, r)
if __name__ == '__main__':
arr = [12, 3, 5, 7, 4, 19, 26]
n = len(arr)
k=3
print("K'th smallest element is",
kthSmallest(arr, 0, n - 1, k))
OUTPUT:

K'th smallest element is 5

RESULT:
Thus to implement randomized algorithms for finding the kth smallest
number using Quick select was written and verified successfully.

You might also like