def unique_element(arr):
for i in range(0, len(arr)-2):
for j in range(i+1, len(arr)):
if arr[i] == arr[j]:
return False
return True
def binary(n):
count = 1
while n > 1:
count += 1
n /= 2
return count
def binary_rec(n):
if n == 1: return 1
return binary_rec(n//2) + 1
def merge(my_list, aux, lo, mid, hi):
# copy items from my_list to aux list
aux[lo:hi+1] = my_list[lo:hi+1]
i = lo
j = mid + 1
# i ----> mid | j ----> hi
for k in range(lo, hi+1):
if i > mid: # i cross mid, copy from j half
my_list[k] = aux[j]
j += 1
elif j > hi: # j cross hi, copy from i half
my_list[k] = aux[i]
i += 1
elif aux[j] < aux[i]:
my_list[k] = aux[j]
j += 1
else:
my_list[k] = aux[i]
i+= 1
def merge_sort(my_list, aux, lo, hi):
if hi <= lo: return
mid = (hi + lo) // 2
divide(my_list, aux, lo, mid) # first half lo --> mid
divide(my_list, aux, mid + 1, hi) # second half mid+1 --> hi
merge(my_list, aux, lo, mid, hi) # sort lo --> hi
def swap(numbers, i, j):
temp = numbers[i]
numbers[i] = numbers[j]
numbers[j] = temp
def quick_sort(numbers, lo, hi):
if lo < hi:
# choose partition type
s = partition(numbers, lo, hi)
quick_sort(numbers, lo, s - 1)
quick_sort(numbers, s + 1, hi)
return numbers
"""
Partitions subarray by Lomuto’s algorithm using first element as pivot.
Output: Partition of numbers and the new position of the pivot.
"""
def lomuto_partition(numbers, lo, hi):
pivot = numbers[lo]
s = lo
for i in range(lo+1, hi):
# If current element is smaller than or equal to pivot
if numbers[i] <= pivot:
# increment index of smaller element
s += 1
swap(numbers, s, i)
swap(numbers, lo, s)
return s
"""
Partitions subarray by Hoare’s algorithm using first element as pivot.
Output: Partition of numbers with the split position returned as this
function’s value
"""
def hoare_partition(numbers, lo, hi):
p = numbers[lo]
i = lo+1
j = hi
while i < j:
while numbers[i] < p:
i += 1
while numbers[j] > p:
j -= 1
swap(numbers, i, j)
swap(numbers, i, j)
swap(numbers, lo, j)
return j
from collections import defaultdict
import heapq
def prims(graph, s):
mst = defaultdict(set)
visited = set([s])
edges = [
(cost, s, w)
for w, cost in graph[s]
]
[Link](edges)
while edges:
cost, v, w = [Link](edges)
if w not in visited and w in graph:
[Link](w)
mst[v].add(w)
for adj, cost in graph[w]:
if adj not in visited:
[Link](edges, (cost, w, adj))
return mst
graph = {
'A': {('C', 31)},
'B': {('C', 15)},
'C': {('G', 77), ('H', 40)},
'E': {('C', 17), ('I', 3)},
'G': {('B', 22), ('E', 23)},
'H': {('G', 66)},
'I': {('J', 70), ('K', 31)},
}
print(prims(graph, 'A'))
# Time-Complexity O(E log V)
from queue import PriorityQueue
def dijkstra(graph, s):
seen = set()
cost = {s: 0}
parent_path = {s: None}
pq = PriorityQueue()
[Link]((0, s))
while not [Link]():
_, v = [Link]()
[Link](v)
for w, distance in graph[v]:
if w in seen: continue
old_cost = [Link](w, float('inf'))
new_cost = cost[v] + distance
if new_cost < old_cost:
[Link]((new_cost, w))
cost[w] = new_cost
parent_path[w] = v
return parent_path
G = {
'A': {('C', 31)},
'B': {('C', 15), ('J', 58)},
'C': {('C', 60), ('G', 77), ('H', 40)},
'E': {('C', 17), ('E', 55), ('I', 3)},
'G': {('B', 22), ('E', 23), ('G', 31)},
'H': {('G', 66)},
'I': {('J', 70), ('K', 31)},
'J': {('H', 8), ('K', 28)},
'K': {('I', 13)}
}
parent_path = dijkstra(G, 'A')