# === 1. Связный список (LinkedList) === def ll_insert(head, name, phone): # Вставка новой записи или обновление существующей if head is None: return {'name': name, 'phone': phone, 'next': None} current = head # Ищем, есть ли уже запись с этим именем while current is not None: if current['name'] == name: current['phone'] = phone # Обновляем телефон return head current = current["next"] # Если не нашли, добавляем в конец current = head while current['next'] is not None: current = current['next'] current['next'] = {'name': name, 'phone': phone, 'next': None} return head def ll_find(head, name): """Ищет запись по имени, возвращает телефон или None.""" current = head while current: if current['name'] == name: return current['phone'] current = current['next'] return None def ll_delete(head, name): current = head previous = None while current is not None: if current['name'] == name: if previous is None: return current['next'] previous['next'] = current['next'] return head previous = current current = current['next'] return head def ll_list_all(head): #Собирает все записи в отсортированный список кортежей. records = [] current = head while current: records.append((current['name'], current['phone'])) current = current['next'] # Сортируем по имени return sorted(records, key=lambda x: x[0]) # === 2. Хеш-таблица (HashTable) === def my_hash(s, M): B = 31 n = len(s) h = 0 for i in range(n): h += ord(s[i]) * (B ** (n - 1 - i)) return h % M def ht_insert(buckets, name, phone): index = my_hash(name, len(buckets)) # Вставляем в соответствующий бакет buckets[index] = ll_insert(buckets[index], name, phone) return buckets def ht_find(buckets, name): index = my_hash(name, len(buckets)) # Ищем внутри бакета return ll_find(buckets[index], name) def ht_delete(buckets, name): index = my_hash(name, len(buckets)) # Удаляем внутри бакета buckets[index] = ll_delete(buckets[index], name) return buckets def ht_list_all(buckets): # Собираем все записи из бакетов result = [] for i in range(len(buckets)): result += ll_list_all(buckets[i]) # Сортируем по имени result.sort(key=lambda x: x[0]) return result # === 3. Двоичное дерево поиска (BST) === def bst_insert(root, name, phone): if root is None: return {'name': name, 'phone': phone,'left': None, 'right': None} current = root while True: # если такое имя уже есть — меняем телефон if name == current['name']: current['phone'] = phone return root # если новое имя меньше — идём влево if name < current['name']: if current['left'] is None: current['left'] = {'name': name, 'phone': phone,'left': None, 'right': None} return root current = current['left'] # если новое имя больше — идём вправо else: if current['right'] is None: current['right'] = {'name': name, 'phone': phone,'left': None, 'right': None} return root current = current['right'] def bst_find(root, name): current = root while current is not None: if name == current['name']: return current['phone'] if name < current['name']: current = current['left'] else: current = current['right'] return None def bst_delete(root, name): current = root previous = None while current is not None and current['name'] != name: previous = current if name < current['name']: current = current['left'] else: current = current['right'] # если не нашли if current is None: return root # 2. Если у узла два потомка if current['left'] is not None and current['right'] is not None: successor_parent = current successor = current['right'] # ищем минимальный узел в правом поддереве while successor['left'] is not None: successor_parent = successor successor = successor['left'] # копируем данные successor в current current['name'] = successor['name'] current['phone'] = successor['phone'] # теперь удаляем successor current = successor previous = successor_parent #3 if current['left'] is not None: child = current['left'] else: child = current['right'] # 4. Если удаляем корень if previous is None: return child # 5. Переподключаем родителя if previous['left'] is current: previous['left'] = child else: previous['right'] = child return root def bst_list_all(root): result = [] def inorder(node): if node is None: return inorder(node['left']) result.append((node['name'], node['phone'])) inorder(node['right']) inorder(root) return result