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