def ll_insert(head, name, phone): """ проходит до конца (или сразу добавляет в конец) возвращает новую голову (если вставка в начало) или изменяет список по ссылке. """ new_node = {'name': name, 'phone': phone, 'next': None} # в случае пустого списка, новый узел становится головой if head is None: return new_node # в противном случае проходим в конец списка current = head while current['next'] is not None: if current['name'] == name: current['phone'] = phone return head current = current['next'] # проверяем последний узел if current['name'] == name: current['phone'] = phone else: current['next'] = new_node return head def ll_find(head, name): """ ищет узел по имени. возвращает телефон или None """ current = head while current is not None: if current['name'] == name: return current['phone'] current = current['next'] return None def ll_delete(head, name): """ удаляет узел по имени. возвращает новую голову. """ # если список пуст if head is None: return None # если удаляем голову if head['name'] == name: new_head = head['next'] head['next'] = None return new_head # ищем узел для удаления current = head while current['next'] is not None: if current['next']['name'] == name: target = current['next'] current['next'] = target['next'] target['next'] = None # разрываем связь у удаляемого узла (иными словами, обнуление ссылки) return head current = current['next'] return head def ll_collect(head, result_list): """собирает все данные из связного списка в result_list""" current = head while current is not None: result_list.append((current['name'], current['phone'])) current = current['next'] def ll_list_all(head): """ собирает все записи в список и сортирует """ result = [] current = head while current is not None: result.append((current['name'], current['phone'])) current = current['next'] # ручная сортировка пузырьком n = len(result) for i in range(n): for j in range(0, n - i - 1): if result[j][0] > result[j + 1][0]: result[j], result[j + 1] = result[j + 1], result[j] return result def hash_table(size): """создание хеш-таблицы""" return [None] * size def hash_func(name, buckets_count): """ использует умножение на простое число для лучшего распределения """ h = 0 multiplier = 1 for char in name: h = (h + ord(char) * multiplier) % buckets_count multiplier = (multiplier * 31) % buckets_count return h def ht_insert(buckets, name, phone): """добавить или обновить запись""" if buckets is None: return index = hash_func(name, len(buckets)) buckets[index] = ll_insert(buckets[index], name, phone) def ht_find(buckets, name): """найти телефон по имени""" idx = hash_func(name, len(buckets)) return ll_find(buckets[idx], name) def ht_delete(buckets, name): """ удалить запись """ idx = hash_func(name, len(buckets)) buckets[idx] = ll_delete(buckets[idx], name) def bubble_sort(records): """пузырьковая сортировка""" n = len(records) for i in range(n - 1): swapped = False for j in range(n - 1 - i): if records[j][0] > records[j + 1][0]: records[j], records[j + 1] = records[j + 1], records[j] swapped = True if not swapped: break return records def ht_list_all(buckets): """ собрание всех записей и сортировка """ # Собираем все записи full_data = [] for head in buckets: ll_collect(head, full_data) # Сортируем пузырьком bubble_sort(full_data) return full_data Hash_table1 = hash_table(3) ht_insert(Hash_table1, 'Alena', '010') ht_insert(Hash_table1, 'Helena', '111') ht_insert(Hash_table1, 'Gena', '222') print(ht_list_all(Hash_table1))