0% found this document useful (0 votes)
14 views

Different Python Functions

Uploaded by

AB
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views

Different Python Functions

Uploaded by

AB
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

# Binary Tree

class BinarySearchTreeNode:
def __init__(self, data):
self.data = data
self.left = None
self.right = None

def add_child(self, data):


if data == self.data:
return # node already exist

if data < self.data:


if self.left:
self.left.add_child(data)
else:
self.left = BinarySearchTreeNode(data)
else:
if self.right:
self.right.add_child(data)
else:
self.right = BinarySearchTreeNode(data)

def search(self, val):


if self.data == val:
return True

if val < self.data:


if self.left:
return self.left.search(val)
else:
return False

if val > self.data:


if self.right:
return self.right.search(val)
else:
return False

def in_order_traversal(self):
elements = []
if self.left:
elements += self.left.in_order_traversal()

elements.append(self.data)

if self.right:
elements += self.right.in_order_traversal()
return elements

def delete(self, val):


if val < self.data:
if self.left:
self.left = self.left.delete(val)
elif val > self.data:
if self.right:
self.right = self.right.delete(val)
else:
if self.left is None and self.right is None:
return None
elif self.left is None:
return self.right
elif self.right is None:
return self.left

min_val = self.right.find_min()
self.data = min_val
self.right = self.right.delete(min_val)

return self

def find_max(self):
if self.right is None:
return self.data
return self.right.find_max()

def find_min(self):
if self.left is None:
return self.data
return self.left.find_min()

def build_tree(elements):
print("Building tree with these elements:",elements)
root = BinarySearchTreeNode(elements[0])

for i in range(1,len(elements)):
root.add_child(elements[i])

return root

if __name__ == '__main__':
numbers_tree = build_tree([17, 4, 1, 20, 9, 23, 18, 34])
numbers_tree.delete(20)
print("After deleting 20 ",numbers_tree.in_order_traversal()) # this
should print [1, 4, 9, 17, 18, 23, 34]
numbers_tree = build_tree([17, 4, 1, 20, 9, 23, 18, 34])
numbers_tree.delete(9)
print("After deleting 9 ",numbers_tree.in_order_traversal()) # this
should print [1, 4, 17, 18, 20, 23, 34]

numbers_tree = build_tree([17, 4, 1, 20, 9, 23, 18, 34])


numbers_tree.delete(17)
print("After deleting 17 ",numbers_tree.in_order_traversal()) # this
should print [1, 4, 9, 18, 20, 23, 34]

# Tree

class TreeNode:
def __init__(self, data):
self.data = data
self.children = []
self.parent = None

def get_level(self):
level = 0
p = self.parent
while p:
level += 1
p = p.parent

return level

def print_tree(self):
spaces = ' ' * self.get_level() * 3
prefix = spaces + "|__" if self.parent else ""
print(prefix + self.data)
if self.children:
for child in self.children:
child.print_tree()

def add_child(self, child):


child.parent = self
self.children.append(child)

def build_product_tree():
root = TreeNode("Electronics")

laptop = TreeNode("Laptop")
laptop.add_child(TreeNode("Mac"))
laptop.add_child(TreeNode("Surface"))
laptop.add_child(TreeNode("Thinkpad"))
cellphone = TreeNode("Cell Phone")
cellphone.add_child(TreeNode("iPhone"))
cellphone.add_child(TreeNode("Google Pixel"))
cellphone.add_child(TreeNode("Vivo"))

tv = TreeNode("TV")
tv.add_child(TreeNode("Samsung"))
tv.add_child(TreeNode("LG"))

root.add_child(laptop)
root.add_child(cellphone)
root.add_child(tv)

root.print_tree()

if __name__ == '__main__':
build_product_tree()

# Function for Linked List

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

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

def print(self):
if self.head is None:
print("Linked list is empty")
return
itr = self.head
llstr = ''
while itr:
llstr += str(itr.data)+' --> ' if itr.next else str(itr.data)
itr = itr.next
print(llstr)

def get_length(self):
count = 0
itr = self.head
while itr:
count+=1
itr = itr.next

return count
def insert_at_begining(self, data):
node = Node(data, self.head)
self.head = node

def insert_at_end(self, data):


if self.head is None:
self.head = Node(data, None)
return

itr = self.head

while itr.next:
itr = itr.next

itr.next = Node(data, None)

def insert_at(self, index, data):


if index<0 or index>self.get_length():
raise Exception("Invalid Index")

if index==0:
self.insert_at_begining(data)
return

count = 0
itr = self.head
while itr:
if count == index - 1:
node = Node(data, itr.next)
itr.next = node
break

itr = itr.next
count += 1

def remove_at(self, index):


if index<0 or index>=self.get_length():
raise Exception("Invalid Index")

if index==0:
self.head = self.head.next
return

count = 0
itr = self.head
while itr:
if count == index - 1:
itr.next = itr.next.next
break

itr = itr.next
count+=1

def insert_values(self, data_list):


self.head = None
for data in data_list:
self.insert_at_end(data)

if __name__ == '__main__':
ll = LinkedList()
ll.insert_values(["banana","mango","grapes","orange"])
ll.insert_at(1,"blueberry")
ll.remove_at(2)
ll.print()

ll.insert_values([45,7,12,567,99])
ll.insert_at_end(67)
ll.print()

# Graphs
class Graph:
def __init__(self, edges):
self.edges = edges
self.graph_dict = {}
for start, end in edges:
if start in self.graph_dict:
self.graph_dict[start].append(end)
else:
self.graph_dict[start] = [end]
print("Graph Dict:", self.graph_dict)

def get_paths(self, start, end, path=[]):


path = path + [start]

if start == end:
return [path]

if start not in self.graph_dict:


return []

paths = []
for node in self.graph_dict[start]:
if node not in path:
new_paths = self.get_paths(node, end, path)
for p in new_paths:
paths.append(p)

return paths

def get_shortest_path(self, start, end, path=[]):


path = path + [start]

if start == end:
return path

if start not in self.graph_dict:


return None

shortest_path = None
for node in self.graph_dict[start]:
if node not in path:
sp = self.get_shortest_path(node, end, path)
if sp:
if shortest_path is None or len(sp) < len(shortest_path):
shortest_path = sp

return shortest_path

if __name__ == '__main__':

routes = [
("Mumbai","Pune"),
("Mumbai", "Surat"),
("Surat", "Bangaluru"),
("Pune","Hyderabad"),
("Pune","Mysuru"),
("Hyderabad","Bangaluru"),
("Hyderabad", "Chennai"),
("Mysuru", "Bangaluru"),
("Chennai", "Bangaluru")
]

routes = [
("Mumbai", "Paris"),
("Mumbai", "Dubai"),
("Paris", "Dubai"),
("Paris", "New York"),
("Dubai", "New York"),
("New York", "Toronto"),
]

route_graph = Graph(routes)
start = "Mumbai"
end = "New York"

print(f"All paths between: {start} and {end}:


",route_graph.get_paths(start,end))
print(f"Shortest path between {start} and {end}: ",
route_graph.get_shortest_path(start,end))

start = "Dubai"
end = "New York"

print(f"All paths between: {start} and {end}:


",route_graph.get_paths(start,end))
print(f"Shortest path between {start} and {end}: ",
route_graph.get_shortest_path(start,end))

# Function for Breadth First Search

def bfs(data, start, visited=set()):

queue = [start]

while queue:
current_node = queue.pop(0)
if current_node not in visited:
print(current_node, end=" ")
visited.add(current_node)

for i in data[current_node] - visited:


queue.append(i)
return

if __name__ == '__main__':

data = {
'A': {'B'}, 'B': {'A', 'C', 'D'}, 'C': {'B', 'E'}, 'D': {'B', 'E'},
'E': {'C', 'D', 'F'}, 'F': {'E'}
}

bfs(data, 'A')

# function for depth first search


def dfs(data, start, visited=set()):

# if not visited print it


if start not in visited:
print(start, end=" ")
visited.add(start)

for i in data[start] - visited:

# if not visited gi in depth of it


dfs(data, i, visited)
return

# sample data in dictionary form


data = {
'A': {'B'},
'B': {'A', 'C', 'D'},
'C': {'B', 'E'},
'D': {'B', 'E'},
'E': {'C', 'D', 'F'},
'F': {'E'}
}

if __name__ == '__main__':

dfs(data, 'A')

# Function for Selection Sort

def selection_sort(arr):
size = len(arr)
for i in range(size-1):
min_index = i
for j in range(min_index+1,size):
if arr[j] < arr[min_index]:
min_index = j
if i != min_index:
arr[i], arr[min_index] = arr[min_index], arr[i]

if __name__ == '__main__':
tests = [
[89, 78, 61, 53, 23, 21, 17, 12, 9, 7, 6, 2, 1],
[],
[1,5,8,9],
[234,3,1,56,34,12,9,12,1300],
[78, 12, 15, 8, 61, 53, 23, 27],
[5]
]
for elements in tests:
selection_sort(elements)
print(elements)

# Function for Shell Sort

def shell_sort(arr):
size = len(arr)
gap = size//2

while gap > 0:


for i in range(gap,size):
anchor = arr[i]
j = i
while j>=gap and arr[j-gap]>anchor:
arr[j] = arr[j-gap]
j -= gap
arr[j] = anchor
gap = gap // 2

def foo(arr):
size = len(arr)
gap = size // 2
gap = 3
for i in range(gap, size):
anchor = arr[i]
j = i
while j>=gap and arr[j-gap]>anchor:
arr[j] = arr[j-gap]
j -= gap
arr[j] = anchor

if __name__ == '__main__':
tests = [
[89, 78, 61, 53, 23, 21, 17, 12, 9, 7, 6, 2, 1],
[],
[1,5,8,9],
[234,3,1,56,34,12,9,12,1300],
[5]
]
elements = [89,78,61,53,23,21,17,12,9,7,6,2,1]
for elements in tests:
shell_sort(elements)
print(elements)

# Function for Merge Sort

def merge_sort(arr):
if len(arr) <= 1:
return
mid = len(arr)//2

left = arr[:mid]
right = arr[mid:]

merge_sort(left)
merge_sort(right)

merge_two_sorted_lists(left, right, arr)

def merge_two_sorted_lists(a,b,arr):
len_a = len(a)
len_b = len(b)

i = j = k = 0

while i < len_a and j < len_b:


if a[i] <= b[j]:
arr[k] = a[i]
i+=1
else:
arr[k] = b[j]
j+=1
k+=1

while i < len_a:


arr[k] = a[i]
i+=1
k+=1

while j < len_b:


arr[k] = b[j]
j+=1
k+=1

if __name__ == '__main__':
test_cases = [
[10, 3, 15, 7, 8, 23, 98, 29],
[],
[3],
[9,8,7,2],
[1,2,3,4,5]
]

for arr in test_cases:


merge_sort(arr)
print(arr)
# Function for Insertion Sort

def insertion_sort(elements):
for i in range(1, len(elements)):
anchor = elements[i]
j = i - 1
while j>=0 and anchor < elements[j]:
elements[j+1] = elements[j]
j = j - 1
elements[j+1] = anchor

if __name__ == '__main__':
elements = [11,9,29,7,2,15,28]
insertion_sort(elements)
print(elements)
#
tests = [
[11,9,29,7,2,15,28],
[3, 7, 9, 11],
[25, 22, 21, 10],
[29, 15, 28],
[],
[6]
]

for elements in tests:


insertion_sort(elements)
print(f'sorted array: {elements}')

# implementation of quick sort in python using hoare partition scheme

def swap(a, b, arr):


if a!=b:
tmp = arr[a]
arr[a] = arr[b]
arr[b] = tmp

def quick_sort(elements, start, end):


if start < end:
pi = partition(elements, start, end)
quick_sort(elements, start, pi-1)
quick_sort(elements, pi+1, end)

def partition(elements, start, end):


pivot_index = start
pivot = elements[pivot_index]
while start < end:
while start < len(elements) and elements[start] <= pivot:
start+=1

while elements[end] > pivot:


end-=1

if start < end:


swap(start, end, elements)

swap(pivot_index, end, elements)

return end

if __name__ == '__main__':
elements = [11,9,29,7,2,15,28]
# elements = ["mona", "dhaval", "aamir", "tina", "chang"]
quick_sort(elements, 0, len(elements)-1)
print(elements)

tests = [
[11,9,29,7,2,15,28],
[3, 7, 9, 11],
[25, 22, 21, 10],
[29, 15, 28],
[],
[6]
]

for elements in tests:


quick_sort(elements, 0, len(elements)-1)
print(f'sorted array: {elements}')

# Function for Bubble Sort


# you can use this to sort strings too
def bubble_sort(elements):
size = len(elements)

for i in range(size-1):
swapped = False
for j in range(size-1-i):
if elements[j] > elements[j+1]:
tmp = elements[j]
elements[j] = elements[j+1]
elements[j+1] = tmp
swapped = True

if not swapped:
break

if __name__ == '__main__':
elements = [5,9,2,1,67,34,88,34]
elements = [1,2,3,4,2]
elements = ["mona", "dhaval", "aamir", "tina", "chang"]

bubble_sort(elements)
print(elements)

# Function for Binary Search


from util import time_it

@time_it
def linear_search(numbers_list, number_to_find):
for index, element in enumerate(numbers_list):
if element == number_to_find:
return index
return -1

@time_it
def binary_search(numbers_list, number_to_find):
left_index = 0
right_index = len(numbers_list) - 1
mid_index = 0

while left_index <= right_index:


mid_index = (left_index + right_index) // 2
mid_number = numbers_list[mid_index]

if mid_number == number_to_find:
return mid_index

if mid_number < number_to_find:


left_index = mid_index + 1
else:
right_index = mid_index - 1

return -1

def binary_search_recursive(numbers_list, number_to_find, left_index,


right_index):
if right_index < left_index:
return -1

mid_index = (left_index + right_index) // 2


if mid_index >= len(numbers_list) or mid_index < 0:
return -1
mid_number = numbers_list[mid_index]

if mid_number == number_to_find:
return mid_index

if mid_number < number_to_find:


left_index = mid_index + 1
else:
right_index = mid_index - 1

return binary_search_recursive(numbers_list, number_to_find, left_index,


right_index)

if __name__ == '__main__':
numbers_list = [12, 15, 17, 19, 21, 24, 45, 67]
number_to_find = 21

index = binary_search_recursive(numbers_list, number_to_find, 0,


len(numbers_list))
print(f"Number found at index {index} using binary search")

You might also like