import random as rnd import time ############################################################################################# def sort_list(name_list): l = len(name_list) for i in range(l - 1): for j in range(l - i - 1): if name_list[j][0] > name_list[j + 1][0]: name_list[j], name_list[j + 1] = name_list[j + 1], name_list[j] return name_list def hash_key(name): h_key = sum(ord(ch) for ch in name) return h_key def create_name_phone(i): name = f"User_{i:03d}" phone = f"{rnd.randint(100, 999)}-{rnd.randint(100, 999)}" return (name, phone) ########################################################################################################################### def ll_insert(head, name, phone): next_node = {'name': name, 'phone': phone, 'next': None} if head is None: return next_node running = head while running is not None: if running['name'] == name: running['phone'] = phone return head running = running['next'] running = head while running['next'] is not None: running = running['next'] running['next'] = next_node return head def ll_find(head, name): running = head while True: if running['name'] == name: return running['phone'] running = running['next'] if running is None: break return None def ll_delete(head, name): running = head if running['name'] == name: return head['next'] while running['next']['name'] != name: running = running['next'] if running['next']['next'] is None: if running['next']['name'] != name: return head if running['next']['next'] is None: running['next'] = None else: running['next'] = running['next']['next'] return head def ll_list_all(head): name_list = [] running = head while running is not None: name_list.append((running['name'], running['phone'])) running = running['next'] return name_list ################################################################################################################################ def LinkedList(head, phone_book): start_insert = time.perf_counter() for i in range(len(phone_book)): head = ll_insert(head, phone_book[i][0], phone_book[i][1]) #print(head) end_insert = time.perf_counter() time_insert = end_insert - start_insert start_find = time.perf_counter() for _ in range(100): name = create_name_phone(rnd.randint(0, 999))[0] phone = ll_find(head, name) #print(name, ":", phone) end_find = time.perf_counter() time_find = end_find - start_find start_delete = time.perf_counter() for i in range(110): if i <= 99: name = f"User_{rnd.randint(0,999):03d}" else: name = f"None_{i:03d}" head = ll_delete(head, name) end_delete = time.perf_counter() time_delete = end_delete - start_delete start_list = time.perf_counter() name_list = sort_list(ll_list_all(head)) #print(*name_list) end_list = time.perf_counter() time_list = end_list - start_list return (time_insert, time_find, time_delete, time_list) ######################################################################################################### def ht_insert(buckest, name, phone): index = hash_key(name) % 10 for i, (Name, Phone) in enumerate(buckest[index]): if Name == name: buckest[index][i] = (name, phone) return buckest buckest[index].append((name, phone)) return buckest def ht_find(buckest, name): index = hash_key(name) % 10 for (Name, Phone) in buckest[index]: if Name == name: return Phone return None def ht_list_all(buckest): name_list = [] for index in range(len(buckest)): for i, (name, phone) in enumerate(buckest[index]): name_list.append((name, phone)) name_list = sort_list(name_list) return name_list def ht_delete(buckest, name): index = hash_key(name) % 10 for i, (Name, Phone) in enumerate(buckest[index]): if Name == name: del buckest[index][i] return buckest #################################################################################################### def HashTable(buckest, phone_book): start_insert = time.perf_counter() for i in range(len(phone_book)): buckest = ht_insert(buckest, phone_book[i][0], phone_book[i][1]) #print(buckest) end_insert = time.perf_counter() time_insert = end_insert - start_insert start_find = time.perf_counter() for _ in range(100): name = create_name_phone(rnd.randint(0, 999))[0] phone = ht_find(buckest, name) #print(name, ":", phone) end_find = time.perf_counter() time_find = end_find - start_find start_delete = time.perf_counter() for i in range(110): if i <= 99: name = f"User_{rnd.randint(0,999):03d}" else: name = f"None_{i:03d}" buckest = ht_delete(buckest, name) end_delete = time.perf_counter() time_delete = end_delete - start_delete start_list = time.perf_counter() name_list = sort_list(ht_list_all(buckest)) #print(*name_list) end_list = time.perf_counter() time_list = end_list - start_list return (time_insert, time_find, time_delete, time_list) ################################################################################################# def bst_insert(root, name, phone): running = root if running is None: root = {'name': name, 'phone': phone, 'left': None, 'right': None} return root while True: node = hash_key(running['name']) sheet = hash_key(name) if node < sheet: if running['right'] is None: running['right'] = {'name': name, 'phone': phone, 'left': None, 'right': None} return root running = running['right'] elif node > sheet: if running['left'] is None: running['left'] = {'name': name, 'phone': phone, 'left': None, 'right': None} return root running = running['left'] else: running['phone'] = phone return root def bst_find(root, name): running = root while running is not None: node = hash_key(running['name']) sheet = hash_key(name) if name == running['name']: return running['phone'] elif node < sheet: running = running['right'] else: running = running['left'] return None def bst_list_all(root, name_list = []): if root is None: return name_list.append((root['name'], root['phone'])) bst_list_all(root['left'], name_list) bst_list_all(root['right'], name_list) name_list = sort_list(name_list) return name_list def bst_delete(root, name): if root is None: return None if hash_key(name) < hash_key(root['name']): root['left'] = bst_delete(root['left'], name) elif hash_key(name) > hash_key(root['name']): root['right'] = bst_delete(root['right'], name) else: if root['left'] is None and root['right'] is None: return None if root['left'] is None: return root['right'] if root['right'] is None: return root['left'] min_node = root['right'] while min_node['left'] is not None: min_node = min_node['left'] root['name'] = min_node['name'] root['phone'] = min_node['phone'] root['right'] = bst_delete(root['right'], min_node['name']) return root ################################################################################################# def BinarySearchTree(root): print('=========== TESTING BST_INSERT =============') Name = ['Dima', 'Alex', 'Ivan', 'Maxim', 'Olga', 'Lena'] for _ in range(10): name = Name[rnd.randint(0, len(Name) - 1)] phone = str(rnd.randint(0,9)) + str(rnd.randint(0,9)) + str(rnd.randint(0,9)) + '-' + \ str(rnd.randint(0,9)) + str(rnd.randint(0,9)) + str(rnd.randint(0,9)) print(name, phone) root = bst_insert(root, name, phone) print(root) print('-----------------------------------------------------\n') print('============= END TESTING =====================\n\n') print('============== TESTING BST_FIND =====================') Name.append('Masha') for i in range(len(Name)): name = Name[i] print(name, ":", bst_find(root, name)) print("======== END TESTING =============\n\n") print('===================== TESTING BST_LIST_ALL =============') name_list = bst_list_all(root) print(*name_list) print("======== END TESTING =============\n\n") print('========== TESTING HT_DELETE ==========') for _ in range(2): name = Name[rnd.randint(0, len(Name) - 1)] root = bst_delete(root, name) print(root) print(name, ":", bst_find(root, name)) print("========= END TESTING ==============\n\n") ################################################################################################ def main(): phone_book = [] for i in range(1000): phone_book.append(create_name_phone(i)) for _ in range(9000): phone_book.append(create_name_phone(rnd.randint(0, 999))) phone_book_not_sorted = phone_book.copy() rnd.shuffle(phone_book_not_sorted) phone_book_sorted = phone_book.copy() phone_book_sorted = sort_list(phone_book_sorted) replay = 5 Time_ll_not_sorted = [] Time_ll_sorted = [] Time_average_ll_not_sorted = {'insert': 0, 'find': 0, 'delete': 0, 'list': 0} Time_average_ll_sorted = {'insert': 0, 'find': 0, 'delete': 0, 'list': 0} for _ in range(replay): time_ll_not_sorted = LinkedList(None, phone_book_not_sorted) Time_ll_not_sorted.append({'insert': time_ll_not_sorted[0], 'find': time_ll_not_sorted[1], 'delete': time_ll_not_sorted[2], 'list': time_ll_not_sorted[3]}) for i, key in enumerate(Time_average_ll_not_sorted): Time_average_ll_not_sorted[key] += time_ll_not_sorted[i]/replay for i in range(replay): print(Time_ll_not_sorted[i]) print("Average:", Time_average_ll_not_sorted, "\n\n") for _ in range(replay): time_ll_sorted = LinkedList(None, phone_book_sorted) Time_ll_sorted.append({'insert': time_ll_sorted[0], 'find': time_ll_sorted[1], 'delete': time_ll_sorted[2], 'list': time_ll_sorted[3]}) for i, key in enumerate(Time_average_ll_sorted): Time_average_ll_sorted[key] += time_ll_sorted[i]/replay for i in range(replay): print(Time_ll_not_sorted[i]) print("Average:", Time_average_ll_sorted, "\n\n") Time_ht_not_sorted = [] Time_ht_sorted = [] Time_average_ht_not_sorted = {'insert': 0, 'find': 0, 'delete': 0, 'list': 0} Time_average_ht_sorted = {'insert': 0, 'find': 0, 'delete': 0, 'list': 0} for _ in range(replay): time_ht_not_sorted = HashTable([[] for _ in range(100)], phone_book_not_sorted) Time_ht_not_sorted.append({'insert': time_ht_not_sorted[0], 'find': time_ht_not_sorted[1], 'delete': time_ht_not_sorted[2], 'list': time_ht_not_sorted[3]}) for i, key in enumerate(Time_average_ht_not_sorted): Time_average_ht_not_sorted[key] += time_ht_not_sorted[i]/replay for i in range(replay): print(Time_ht_not_sorted[i]) print(f"Average: {Time_average_ht_not_sorted}\n\n") for _ in range(replay): time_ht_sorted = HashTable([[] for _ in range(100)], phone_book_sorted) Time_ht_sorted.append({'insert': time_ht_sorted[0], 'find': time_ht_sorted[1], 'delete': time_ht_sorted[2], 'list': time_ht_sorted[3]}) for i, key in enumerate(Time_average_ht_sorted): Time_average_ht_sorted[key] += time_ht_sorted[i]/replay for i in range(replay): print(Time_ht_sorted[i]) print(f"Average: {Time_average_ht_sorted}\n\n") #BinarySearchTree(None) if __name__ == "__main__": main()