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

Different Python Functions

Uploaded by

AB
Copyright
© © All Rights Reserved
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
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