Mergesort: Merge2
def merge_sorted_arrays(arr_1, arr_2): def merge_sorted_arrays(arr_1, arr_2):
i=j=k=0 i=j=0
arr_m = [None] * (len(arr_1) + len(arr_2)) arr_m = []
while i < len(arr_1) and j < len(arr_2):
while i < len(arr_1) and j < len(arr_2):
if arr_1[i] < arr_2[j]:
if arr_1[i] < arr_2[j]: arr_m.append(arr_1[i])
arr_m[k] = arr_1[i] i += 1
k += 1 else:
i += 1 arr_m.append(arr_2[j])
else: j += 1
while i < len(arr_1):
arr_m[k] = arr_2[j]
arr_m.append(arr_1[i])
k += 1
i += 1
j += 1 while j < len(arr_2):
while i < len(arr_1): arr_m.append(arr_2[j])
arr_m[k] = arr_1[i] j += 1
k += 1 return arr_m
i += 1
while j < len(arr_2):
arr_1 = [1, 2, 5, 7, 9]
arr_m[k] = arr_2[j] arr_2 = [2, 4, 6, 7, 10]
k += 1 merged_array = merge_sorted_arrays(arr_1, arr_2)
j += 1 print(merged_array)
return arr_m
arr_1 = [1, 2, 5, 7, 9]
arr_2 = [2, 4, 6, 7, 10]
merged_array = merge_sorted_arrays(arr_1, arr_2)
print(merged_array)
def linear_search(X, n, key): X = input("Enter the elements of the list separated by
X.append(key) space: ").split(" ")
i=0 X = [int(i) for i in X]
key = int(input("Enter the key: "))
n = len(X)
while X[i] != key:
i += 1
location = linear_search(X, n, key)
if i < n: if location != -1:
return i print(f"Key found in index: {location}")
else: else:
return -1 print("Key not found in the list")
import math Quickshort:
def partition(arr, start, end):
def merge(A,p,q,r): pivot = arr[end]
n1 = q-p+1 i = start - 1
n2 = r-q for j in range(start, end):
L = [] if arr[j] < pivot:
i += 1
R = []
arr[i], arr[j] = arr[j], arr[i]
for i in range(n1): arr[i + 1], arr[end] = arr[end], arr[i + 1]
L.append(A[p+i]) i += 1
for j in range(n2):
R.append(A[q+1+j]) return i
L.append(math.inf)
R.append(math.inf) def quick_sort(arr, start, end):
#print(L) if start < end:
#print(R) middle = partition(arr, start, end)
i=j=0
quick_sort(arr, start, middle - 1)
for k in range(p,r+1):
quick_sort(arr, middle + 1, end)
if L[i] <= R[j]:
A[k] = L[i] a = input("Enter elements separated by space: ").split(' ')
i+=1 a = [int(i) for i in a]
else: quick_sort(a, 0, len(a) - 1)
A[k] = R[j] print("Sorted data: ", a)
j+=1
Radix:
def merge_sort(A,p,r): def counting_sort(arr, position):
if p < r: n = len(arr)
q = (p+r) // 2 temp = [0] * n
c = [0] * 10
merge_sort(A,p,q)
for item in arr:
#print(A)
digit = (item // position) % 10
merge_sort(A,q+1,r) c[digit] += 1
#print(A) for i in range(1, 10):
c[i] = c[i] + c[i-1]
merge(A,p,q,r) for i in range(n-1, -1, -1):
#print(A) digit = (arr[i] // position) % 10
A = list(map(int,input("Enter your array ").split())) temp[c[digit] - 1] = arr[i]
p=0 c[digit] -= 1
r = len(A) - 1 arr[:] = temp[:]
merge_sort(A,p,r) def radix(arr):
max_element = max(arr)
print(A)
position = 1
while max_element // position > 0:
counting_sort(arr, position)
position = position * 10
arr = [8, 6, 9]
radix(arr)
print(arr)
Count: Knapsack:
n = int(input("Enter the element number:")) def knapsack_01(table, value, weight, i, wt):
arr = [] if i == 0 or wt == 0:
for i in range(n): return 0
num = int(input()) if table[i][wt] != -1:
arr.append(num) return table[i][wt]
largest_number = max(arr)
count = [0] * (largest_number+1) if weight[i] > wt:
for element in arr: return knapsack_01(table, value, weight, i - 1,
count[element] += 1 wt)
for i in range(1, len(count)): else:
count[i] += count[i - 1] take = value[i] + knapsack_01(table, value,
output = [0] * len(arr) weight, i - 1, wt - weight[i])
for item in reversed(arr): leave = knapsack_01(table, value, weight, i - 1,
output[count[item] -1] = item wt)
count[item] -= -1 table[i][wt] = max(take, leave)
print("sorted array", output)
return table[i][wt]
Knapsackk2: n = int(input("Enter the number of items: "))
n = int(input("How many items? ")) value = input("Enter the values of the %d item(s) in
value = [None] * (n+1) order: " % n).split(' ')
weight = [None] * (n+1) value = [int(i) for i in value]
print("Enter imtems' value in separate lines.") value.insert(0, None) # ith item's value at i index
for i in range(1, n+1):
weight = input("Enter the weight of the %d item(s) in
value[i], weight[i] = map(int, input("Item %d: "
order: " % n).split(' ')
%i).split(' '))
capacity = int(input("Capacity: ")) weight = [int(i) for i in weight]
table = [[None for i in range(capacity+1)] for j in weight.insert(0, None) # ith item's weight at i index
range(n+1)] W = int(input("Enter total capacity: "))
for i in range(n+1): table = [[-1 for i in range(W + 1)] for i in range(n + 1)]
for w in range(capacity+1): print("Maximum profit: ", knapsack_01(table, value,
if i == 0 or w == 0: weight, n, W))
table[i][w] = 0
elif weight[i] > w: Coin:
table[i][w] = table[i-1][w] from math import inf
else:
target = int(input("S = "))
table[i][w] = max(table[i-1][w], value[i]+table[i-
coins = list(map(int, input("Enter coins value:
1][w-weight[i]])
").split()))
print(table[n][capacity]) table = [inf] * (target + 1)
print("Selected items: ") table[0] = 0
i=n for s in range(1, target + 1):
w = capacity for c in coins:
while i > 0 and w > 0: if c <= s:
if table[i][w] != table[i-1][w]: count = table[s - c] + 1
print(i, end=' ') if count < table[s]:
w = w - weight[i] table[s] = count
i=i-1
if table[target] == inf:
else:
print("No solution possible")
i = i-1
else:
print(f"Number of coins: {table[target]}")
Coin2: Topologicalsort:
from math import inf # DFS with cycle detection and topological sort
def dfs(u):
global cycle_found
target = int(input("S = "))
color[u] = "gray"
for v in adj[u]:
coins = list(map(int, input("Enter coins value: ").split())) if color[v] == "white":
dfs(v)
elif color[v] == "gray":
table = [inf] * (target + 1) cycle_found = True
table[0] = 0 color[u] = "black"
list_coins = [-1] * (target + 1) topo_order.append(u)
nodes = input("Enter your node: ").split()
for s in range(1, target + 1): e = int(input("Enter the number of edges: "))
for c in coins:
adj = {}
color = {}
if c <=s and table[s-c] + 1 < table[s]:
table[s] = table[s-c] + 1 for node in nodes:
list_coins[s] = c color[node] = "white"
adj[node] = []
if table[target] == inf:
print("No solution possible") for i in range(e):
else: u, v = input(f"Edge {i+1} (u -> v): ").split()
print(f"Number of coins: {table[target]}") adj[u].append(v) # Directed edge only
reasult = []
cycle_found = False
current = target
topo_order = []
while current > 0:
reasult.append(list_coins[current])
current -= list_coins[current] for node in nodes:
if color[node] == "white":
print(f"used coins: {reasult}") dfs(node)
if cycle_found:
print("Cycle detected. Topological sort not
possible.")
else:
print("Topological Order:", "
".join(reversed(topo_order)))
BFS with numpy: Without numpy:
from collections import defaultdict import queue
from queue import Queue
n = int(input("Please enter the number of nodes: ")) def bfs(adj, source):
e = int(input("Please enter the number of edges: ")) visited = [0 for i in range(len(adj))]
# creating adjacency list using dictionary q = queue.Queue(maxsize=len(adj))
adj = defaultdict(list)
for i in range(e): q.put(source)
u, v = input("Edge %d: " % (i + 1)).split() visited[source] = 1
adj[u].append(v)
adj[v].append(u) while not q.empty():
current_node = q.get()
# Performing BFS print(current_node, end=' ')
q = Queue(maxsize=len(adj))
visited = set() for i in range(len(adj[current_node])): # not
s = input("Enter the source node: ") a pythonic way
q.put(s) adjacent_node = adj[current_node][i]
visited.add(s) if visited[adjacent_node] == 0:
visited[adjacent_node] = 1
print("BFS: ", end='') q.put(adjacent_node)
while not q.empty():
u = q.get()
print(u, end=' ') n = int(input("Enter the number of nodes: "))
e = int(input("Enter the number of edges: "))
for element in adj[u]:
if element not in visited: adj_list = [[] for i in range(n)]
q.put(element)
visited.add(element) print("Enter edges in separate lines.")
graph 06 bfs with name.py for i in range(e):
Displaying graph 06 bfs with name.py. u, v = map(int, input().split())
adj_list[u].append(v)
adj_list[v].append(u)
s = int(input('Enter source vertex: '))
print('BFS: ', end="")
bfs(adj_list, s)
graph 05 bfs without name.py
Displaying graph 05 bfs without name.py.
DFS: Withoutnumpy dfs:
def dfs(u): def dfs(adj, visited, current_node):
color[u] = 'gray' if visited[current_node] != 0:
return
for element in adj[u]: visited[current_node] = 1
if color[element] == 'white': for i in range(len(adj[current_node])): # not a
dfs(element) pythonic way
adjacent_node = adj[current_node][i]
if visited[adjacent_node] == 0:
color[u] = 'black' dfs(adj, visited, adjacent_node)
print(u, end=' ') print(current_node, end=' ')
# for neighbour in adj[current_node]: #
pythonic way
# as we want to allow any vertex name not only 0 to # if visited[neighbour] == 0: # if neighbour
n-1 not in visited:
# we need have complete list of all vertices name # dfs(adj, visited, neighbour)
nodes = input("Enter nodes' name: ").split()
e = int(input("Number of edges: ")) n = int(input("Enter the number of nodes: "))
e = int(input("Enter the number of edges: "))
# creating dictionary to store adjacency list of each
vertex adj_list = [[] for i in range(n)]
adj = {}
# creating a dictionary to store color's value of each print("Enter edges in separate lines.")
vertex for i in range(e):
color = {} u, v = map(int, input().split())
# adding all vertex name as key and an empty list as adj_list[u].append(v)
corresponding value adj_list[v].append(u)
# adding white color to each vertex
for element in nodes:
adj[element] = [] print(adj_list)
color[element] = 'white'
visited = [0 for i in range(n)]
# creating adjacency list print('DFS: ', end="")
for i in range(e): for i in range(n):
u, v = input("Edge %d: " % (i + 1)).split() if visited[i] == 0:
adj[u].append(v) dfs(adj_list, visited, i)
# if graph is directed then we must eliminate the """
following line Sample input / output
adj[v].append(u) Enter the number of nodes: 5
graph 08 dfs with name.py Enter the number of edges: 4
Displaying graph 07 dfs without name.py. Enter edges in separate lines.
02
21
23
04
DFS: 1 3 2 4 0
"""
graph 07 dfs without name.py
Displaying graph 07 dfs without name.py.
Kruskals: Prims:
class Graph: # Prim's Algorithm in Python
def __init__(self, vertices): # Fixed constructor
self.V = vertices
self.graph = [] INF = 9999999
def add_edge(self, u, v, w):
self.graph.append([u, v, w]) V=5
def find(self, parent, i):
if parent[i] == i: G = [[0, 9, 75, 0, 0],
return i [9, 0, 95, 19, 42],
return self.find(parent, parent[i]) [75, 95, 0, 51, 66],
def apply_union(self, parent, rank, x, y): [0, 19, 51, 0, 31],
xroot = self.find(parent, x) [0, 42, 66, 31, 0]]
yroot = self.find(parent, y)
if rank[xroot] < rank[yroot]: selected = [0, 0, 0, 0, 0]
parent[xroot] = yroot
elif rank[xroot] > rank[yroot]: no_edge = 0
parent[yroot] = xroot
else: selected[0] = True
parent[yroot] = xroot
rank[xroot] += 1 print("Edge : Weight\n")
def kruskal_algo(self): while (no_edge < V - 1):
result = []
i, e = 0, 0 minimum = INF
self.graph = sorted(self.graph, key=lambda item: x=0
item[2]) y=0
parent = [] for i in range(V):
rank = [] if selected[i]:
for node in range(self.V): for j in range(V):
parent.append(node) if ((not selected[j]) and G[i][j]):
rank.append(0)
while e < self.V - 1: if minimum > G[i][j]:
u, v, w = self.graph[i] minimum = G[i][j]
i=i+1 x=i
x = self.find(parent, u) y=j
y = self.find(parent, v) print(str(x) + "-" + str(y) + ":" + str(G[x][y]))
if x != y: selected[y] = True
e=e+1 no_edge += 1
result.append([u, v, w])
self.apply_union(parent, rank, x, y)
for u, v, weight in result:
print("%d - %d: %d" % (u, v, weight))
g = Graph(6)
g.add_edge(0, 1, 4)
g.add_edge(0, 2, 4)
g.add_edge(1, 2, 2)
g.add_edge(1, 0, 4)
g.add_edge(2, 0, 4)
g.add_edge(2, 1, 2) Dijaskstra:
g.add_edge(2, 3, 3) from queue import PriorityQueue
g.add_edge(2, 5, 2) import math
g.add_edge(2, 4, 4) class Node:
g.add_edge(3, 2, 3) def __init__(self, name):
g.add_edge(3, 4, 3) self.name = name
g.add_edge(4, 2, 4) self.key = math.inf # Distance from source
g.add_edge(4, 3, 3) self.parent = None
g.add_edge(5, 2, 2) self.visited = False
g.add_edge(5, 4, 3) self.adj = [] # List of tuples: (neighbor_node,
weight)
print("Edges in the Minimum Spanning Tree:") def __lt__(self, other): # Needed for
g.kruskal_algo() PriorityQueue
return self.key < other.key
Strongly: def dijkstra(start_node):
from collections import defaultdict start_node.key = 0
q = PriorityQueue()
class Graph: q.put(start_node)
while not q.empty():
def __init__(self, vertex): # Fixed __init__ method u = q.get()
self.V = vertex if u.visited:
self.graph = defaultdict(list) continue
u.visited = True
# Add edge into the graph for v, weight in u.adj:
def add_edge(self, s, d): if not v.visited and u.key + weight < v.key:
self.graph[s].append(d) v.key = u.key + weight
v.parent = u
# DFS q.put(v)
def dfs(self, d, visited_vertex): def get_path(destination):
visited_vertex[d] = True path = []
print(d, end=' ') current = destination
for i in self.graph[d]: while current:
if not visited_vertex[i]: path.append(current.name)
self.dfs(i, visited_vertex) current = current.parent
return path[::-1]
def fill_order(self, d, visited_vertex, stack):
visited_vertex[d] = True # ---------------- Input Section ---------------- #
for i in self.graph[d]:
if not visited_vertex[i]: # Input node names
self.fill_order(i, visited_vertex, stack) node_input = input("Enter nodes name: ").split()
stack.append(d) # Fixed append usage Nodes = {name: Node(name) for name in
node_input}
# Transpose the graph
def transpose(self): # Input number of edges
g = Graph(self.V) num_edges = int(input("NO of edges: "))
for i in self.graph: print("Edge info: (u,v,w)")
for j in self.graph[i]: for i in range(num_edges):
g.add_edge(j, i) edge_input = input(f"Edge {i+1}: ").split()
return g u, v, w = edge_input[0], edge_input[1],
int(edge_input[2])
# Print strongly connected components Nodes[u].adj.append((Nodes[v], w))
def print_scc(self): Nodes[v].adj.append((Nodes[u], w)) # Assuming
stack = [] undirected graph
visited_vertex = [False] * self.V
# Input source and destination
for i in range(self.V): source_name = input("Source node: ")
if not visited_vertex[i]: destination_name = input("Destination node: ")
self.fill_order(i, visited_vertex, stack)
# ---------------- Run Dijkstra ---------------- #
gr = self.transpose() dijkstra(Nodes[source_name])
visited_vertex = [False] * self.V
# ---------------- Output Section ---------------- #
while stack: path = get_path(Nodes[destination_name])
i = stack.pop() cost = Nodes[destination_name].key
if not visited_vertex[i]:
gr.dfs(i, visited_vertex) print(f"\noutput:")
print("") print(f"cost: {cost}")
print("path:", ' '.join(path))
g = Graph(8) for name in node_input:
g.add_edge(0, 1) node = Nodes[name]
g.add_edge(1, 2) parent_name = node.parent.name if node.parent
g.add_edge(2, 3) else node.name
g.add_edge(2, 4) print(f"{node.name}: key = {node.key}, parent =
g.add_edge(3, 0) {parent_name}")
g.add_edge(4, 5)
g.add_edge(5, 6)
g.add_edge(6, 4)
g.add_edge(6, 7)
print("Strongly Connected Components:")
g.print_scc()