[2] Убрана первая работа из ветки
This commit is contained in:
parent
cb04e571d3
commit
9f8e9e1384
|
|
@ -1,477 +0,0 @@
|
|||
import time
|
||||
import random
|
||||
import csv
|
||||
import os
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import sys
|
||||
sys.setrecursionlimit(20000)
|
||||
# Связный список
|
||||
|
||||
def ll_insert(head, name, phone):
|
||||
|
||||
new_node = {'name': name, 'phone': phone, 'next': None}
|
||||
|
||||
if head is None:
|
||||
return new_node
|
||||
|
||||
if head['name'] == name:
|
||||
head['phone'] = phone
|
||||
return head
|
||||
|
||||
current = head
|
||||
while current['next'] is not None:
|
||||
if current['next']['name'] == name:
|
||||
current['next']['phone'] = phone
|
||||
return head
|
||||
current = current['next']
|
||||
|
||||
current['next'] = new_node
|
||||
return head
|
||||
|
||||
def ll_find(head, name):
|
||||
|
||||
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:
|
||||
return head['next']
|
||||
|
||||
current = head
|
||||
while current['next'] is not None:
|
||||
if current['next']['name'] == name:
|
||||
current['next'] = current['next']['next']
|
||||
return head
|
||||
current = current['next']
|
||||
|
||||
return head
|
||||
|
||||
def ll_list_all(head):
|
||||
|
||||
records = []
|
||||
current = head
|
||||
while current is not None:
|
||||
records.append((current['name'], current['phone']))
|
||||
current = current['next']
|
||||
records.sort(key=lambda x: x[0])
|
||||
return records
|
||||
|
||||
# Хэш функции
|
||||
|
||||
def hash_function(name, table_size):
|
||||
return sum(ord(c) for c in name) % table_size
|
||||
|
||||
|
||||
def ht_create(size=1000):
|
||||
return [None] * size
|
||||
|
||||
|
||||
def ht_insert(buckets, name, phone):
|
||||
size = len(buckets)
|
||||
index = hash_function(name, size)
|
||||
buckets[index] = ll_insert(buckets[index], name, phone)
|
||||
|
||||
|
||||
def ht_find(buckets, name):
|
||||
size = len(buckets)
|
||||
index = hash_function(name, size)
|
||||
return ll_find(buckets[index], name)
|
||||
|
||||
|
||||
def ht_delete(buckets, name):
|
||||
size = len(buckets)
|
||||
index = hash_function(name, size)
|
||||
buckets[index] = ll_delete(buckets[index], name)
|
||||
|
||||
|
||||
def ht_list_all(buckets):
|
||||
records = []
|
||||
for bucket in buckets:
|
||||
current = bucket
|
||||
while current is not None:
|
||||
records.append((current['name'], current['phone']))
|
||||
current = current['next']
|
||||
records.sort(key=lambda x: x[0])
|
||||
return records
|
||||
|
||||
# Функции для дерева поиска
|
||||
|
||||
def bst_insert(root, name, phone):
|
||||
|
||||
if root is None:
|
||||
return {'name': name, 'phone': phone, 'left': None, 'right': None}
|
||||
|
||||
if name < root['name']:
|
||||
root['left'] = bst_insert(root['left'], name, phone)
|
||||
elif name > root['name']:
|
||||
root['right'] = bst_insert(root['right'], name, phone)
|
||||
else:
|
||||
root['phone'] = phone
|
||||
|
||||
return root
|
||||
|
||||
|
||||
def bst_find(root, name):
|
||||
|
||||
current = root
|
||||
while current is not None:
|
||||
if name == current['name']:
|
||||
return current['phone']
|
||||
elif name < current['name']:
|
||||
current = current['left']
|
||||
else:
|
||||
current = current['right']
|
||||
return None
|
||||
|
||||
|
||||
def bst_find_min(node):
|
||||
|
||||
current = node
|
||||
while current['left'] is not None:
|
||||
current = current['left']
|
||||
return current
|
||||
|
||||
|
||||
def bst_delete(root, name):
|
||||
|
||||
if root is None:
|
||||
return None
|
||||
|
||||
if name < root['name']:
|
||||
root['left'] = bst_delete(root['left'], name)
|
||||
elif name > root['name']:
|
||||
root['right'] = bst_delete(root['right'], name)
|
||||
else:
|
||||
if root['left'] is None:
|
||||
return root['right']
|
||||
elif root['right'] is None:
|
||||
return root['left']
|
||||
|
||||
min_node = bst_find_min(root['right'])
|
||||
root['name'] = min_node['name']
|
||||
root['phone'] = min_node['phone']
|
||||
root['right'] = bst_delete(root['right'], min_node['name'])
|
||||
|
||||
return root
|
||||
|
||||
|
||||
def bst_list_all(root):
|
||||
|
||||
records = []
|
||||
|
||||
def inorder_traversal(node):
|
||||
if node is not None:
|
||||
inorder_traversal(node['left'])
|
||||
records.append((node['name'], node['phone']))
|
||||
inorder_traversal(node['right'])
|
||||
|
||||
inorder_traversal(root)
|
||||
return records
|
||||
|
||||
# Генерация тестовых данных
|
||||
|
||||
def generate_records(count=10000):
|
||||
|
||||
records = []
|
||||
for i in range(count):
|
||||
name = f"User_{i:05d}"
|
||||
phone = f"+7-{random.randint(100,999)}-{random.randint(100,999)}-{random.randint(1000,9999)}"
|
||||
records.append((name, phone))
|
||||
|
||||
shuffled = records.copy()
|
||||
random.shuffle(shuffled)
|
||||
sorted_records = sorted(records, key=lambda x: x[0])
|
||||
|
||||
return shuffled, sorted_records
|
||||
|
||||
|
||||
|
||||
# Замер времени
|
||||
|
||||
def measure_insertion(structure_name, records):
|
||||
|
||||
times = []
|
||||
filled_structure = None
|
||||
|
||||
for run in range(5):
|
||||
if structure_name == "linked_list":
|
||||
structure = None
|
||||
elif structure_name == "hash_table":
|
||||
structure = ht_create(1000)
|
||||
elif structure_name == "bst":
|
||||
structure = None
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name, phone in records:
|
||||
if structure_name == "linked_list":
|
||||
structure = ll_insert(structure, name, phone)
|
||||
elif structure_name == "hash_table":
|
||||
ht_insert(structure, name, phone)
|
||||
elif structure_name == "bst":
|
||||
structure = bst_insert(structure, name, phone)
|
||||
|
||||
end = time.perf_counter()
|
||||
times.append(end - start)
|
||||
|
||||
if run == 4:
|
||||
filled_structure = structure
|
||||
|
||||
return times, filled_structure
|
||||
|
||||
def measure_search(structure_name, structure, search_names):
|
||||
|
||||
times = []
|
||||
|
||||
for run in range(5):
|
||||
start = time.perf_counter()
|
||||
|
||||
for name in search_names:
|
||||
if structure_name == "linked_list":
|
||||
ll_find(structure, name)
|
||||
elif structure_name == "hash_table":
|
||||
ht_find(structure, name)
|
||||
elif structure_name == "bst":
|
||||
bst_find(structure, name)
|
||||
|
||||
end = time.perf_counter()
|
||||
times.append(end - start)
|
||||
|
||||
return times
|
||||
|
||||
def measure_deletion(structure_name, original_structure, delete_names):
|
||||
|
||||
times = []
|
||||
|
||||
for run in range(5):
|
||||
if structure_name == "linked_list":
|
||||
all_records = ll_list_all(original_structure)
|
||||
test_structure = None
|
||||
for name, phone in all_records:
|
||||
test_structure = ll_insert(test_structure, name, phone)
|
||||
|
||||
elif structure_name == "hash_table":
|
||||
all_records = ht_list_all(original_structure)
|
||||
test_structure = ht_create(1000)
|
||||
for name, phone in all_records:
|
||||
ht_insert(test_structure, name, phone)
|
||||
|
||||
elif structure_name == "bst":
|
||||
all_records = bst_list_all(original_structure)
|
||||
test_structure = None
|
||||
for name, phone in all_records:
|
||||
test_structure = bst_insert(test_structure, name, phone)
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name in delete_names:
|
||||
if structure_name == "linked_list":
|
||||
test_structure = ll_delete(test_structure, name)
|
||||
elif structure_name == "hash_table":
|
||||
ht_delete(test_structure, name)
|
||||
elif structure_name == "bst":
|
||||
test_structure = bst_delete(test_structure, name)
|
||||
|
||||
end = time.perf_counter()
|
||||
times.append(end - start)
|
||||
|
||||
return times
|
||||
|
||||
# Основная часть
|
||||
|
||||
def run_experiment():
|
||||
|
||||
current_dir = os.path.dirname(__name__)
|
||||
docs_dir = os.path.dirname(current_dir)
|
||||
csv_file = os.path.join(docs_dir, "experiment_results.csv")
|
||||
|
||||
print("=" * 70)
|
||||
print("ЭКСПЕРИМЕНТАЛЬНОЕ СРАВНЕНИЕ СТРУКТУР ДАННЫХ")
|
||||
print("Телефонный справочник - 10000 записей")
|
||||
print("=" * 70)
|
||||
print(f"\nРезультаты будут сохранены в: {csv_file}")
|
||||
|
||||
print("\n1. Генерация тестовых данных...")
|
||||
shuffled_records, sorted_records = generate_records(10000)
|
||||
print(f" Сгенерировано 10000 записей")
|
||||
|
||||
existing_names = [shuffled_records[i][0] for i in random.sample(range(10000), 100)]
|
||||
nonexisting_names = [f"NotExist_{i}" for i in range(10)]
|
||||
search_names = existing_names + nonexisting_names
|
||||
delete_names = [shuffled_records[i][0] for i in random.sample(range(10000), 50)]
|
||||
|
||||
results = [["Структура", "Режим", "Операция",
|
||||
"Замер1(с)", "Замер2(с)", "Замер3(с)", "Замер4(с)", "Замер5(с)",
|
||||
"Среднее(с)"]]
|
||||
|
||||
for mode_name, records in [("случайный", shuffled_records),
|
||||
("отсортированный", sorted_records)]:
|
||||
|
||||
print(f"\n2. Тестирование режима: {mode_name}")
|
||||
print("-" * 50)
|
||||
|
||||
for struct_name in ["linked_list", "hash_table", "bst"]:
|
||||
print(f"\n {struct_name.upper()}:")
|
||||
|
||||
print(" Вставка 10000 записей...")
|
||||
insert_times, filled_struct = measure_insertion(struct_name, records)
|
||||
avg_insert = sum(insert_times) / 5
|
||||
print(f" Время: {avg_insert:.4f} сек (среднее)")
|
||||
|
||||
print(" Поиск 110 записей...")
|
||||
search_times = measure_search(struct_name, filled_struct, search_names)
|
||||
avg_search = sum(search_times) / 5
|
||||
print(f" Время: {avg_search:.4f} сек (среднее)")
|
||||
|
||||
print(" Удаление 50 записей...")
|
||||
delete_times = measure_deletion(struct_name, filled_struct, delete_names)
|
||||
avg_delete = sum(delete_times) / 5
|
||||
print(f" Время: {avg_delete:.4f} сек (среднее)")
|
||||
|
||||
results.append([struct_name, mode_name, "вставка"] + insert_times + [avg_insert])
|
||||
results.append([struct_name, mode_name, "поиск"] + search_times + [avg_search])
|
||||
results.append([struct_name, mode_name, "удаление"] + delete_times + [avg_delete])
|
||||
|
||||
print("\n3. Сохранение результатов...")
|
||||
with open(csv_file, "w", newline="", encoding="utf-8") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerows(results)
|
||||
print(f" Результаты сохранены в: {csv_file}")
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("СВОДНАЯ ТАБЛИЦА РЕЗУЛЬТАТОВ")
|
||||
print("=" * 70)
|
||||
print(f"{'Структура':<15} {'Режим':<12} {'Операция':<10} {'Среднее время (сек)':<20}")
|
||||
print("-" * 70)
|
||||
|
||||
for row in results[1:]:
|
||||
struct, mode, op, t1, t2, t3, t4, t5, avg = row
|
||||
print(f"{struct:<15} {mode:<12} {op:<10} {avg:<20.6f}")
|
||||
|
||||
return results, docs_dir
|
||||
|
||||
# Графики
|
||||
|
||||
def create_graphs(results, docs_dir):
|
||||
|
||||
print("\n4. Построение графиков...")
|
||||
|
||||
data = {}
|
||||
for row in results[1:]:
|
||||
struct = row[0]
|
||||
mode = row[1]
|
||||
op = row[2]
|
||||
avg = row[8]
|
||||
|
||||
if struct not in data:
|
||||
data[struct] = {}
|
||||
if mode not in data[struct]:
|
||||
data[struct][mode] = {}
|
||||
data[struct][mode][op] = avg
|
||||
|
||||
|
||||
struct_labels = {
|
||||
'linked_list': 'LinkedList',
|
||||
'hash_table': 'HashTable',
|
||||
'bst': 'BST'
|
||||
}
|
||||
|
||||
|
||||
colors = {
|
||||
'linked_list': '#3498db',
|
||||
'hash_table': '#2ecc71',
|
||||
'bst': '#e74c3c'
|
||||
}
|
||||
|
||||
|
||||
fig, axes = plt.subplots(1, 3, figsize=(15, 6))
|
||||
fig.suptitle('Сравнение производительности структур данных', fontsize=16, fontweight='bold')
|
||||
|
||||
operations = ['вставка', 'поиск', 'удаление']
|
||||
operation_titles = ['Вставка\n(10000 записей)', 'Поиск\n(110 запросов)', 'Удаление\n(50 записей)']
|
||||
modes = ['случайный', 'отсортированный']
|
||||
mode_labels = ['Случайный', 'Отсортированный']
|
||||
|
||||
for idx, (op, op_title) in enumerate(zip(operations, operation_titles)):
|
||||
ax = axes[idx]
|
||||
|
||||
# Позиции для групп столбцов
|
||||
x = np.arange(len(modes)) # [0, 1]
|
||||
width = 0.25 # ширина одного столбца
|
||||
multiplier = 0
|
||||
|
||||
for struct in ['linked_list', 'hash_table', 'bst']:
|
||||
values = [data[struct][mode][op] for mode in modes]
|
||||
offset = width * multiplier
|
||||
bars = ax.bar(x + offset, values, width,
|
||||
label=struct_labels[struct],
|
||||
color=colors[struct],
|
||||
edgecolor='black', linewidth=0.5)
|
||||
|
||||
|
||||
for bar, val in zip(bars, values):
|
||||
if val < 0.01:
|
||||
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + val*0.05,
|
||||
f'{val:.5f}', ha='center', va='bottom', fontsize=8, rotation=0)
|
||||
else:
|
||||
ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + val*0.02,
|
||||
f'{val:.4f}', ha='center', va='bottom', fontsize=8, rotation=0)
|
||||
|
||||
multiplier += 1
|
||||
|
||||
|
||||
ax.set_title(op_title, fontsize=12, fontweight='bold')
|
||||
ax.set_ylabel('Время (секунды)', fontsize=10)
|
||||
ax.set_xlabel('Режим данных', fontsize=10)
|
||||
ax.set_xticks(x + width)
|
||||
ax.set_xticklabels(mode_labels)
|
||||
ax.legend(loc='upper left', fontsize=8)
|
||||
ax.grid(True, alpha=0.3, axis='y')
|
||||
|
||||
|
||||
all_values = [data[s][m][op] for s in ['linked_list', 'hash_table', 'bst'] for m in modes]
|
||||
if max(all_values) / min(all_values) > 100:
|
||||
ax.set_yscale('log')
|
||||
ax.set_ylabel('Время (секунды) - логарифмическая шкала', fontsize=9)
|
||||
|
||||
plt.tight_layout()
|
||||
graph_path = os.path.join(docs_dir, "performance_graphs.png")
|
||||
plt.savefig(graph_path, dpi=150, bbox_inches='tight')
|
||||
plt.close()
|
||||
print(f" Графики сохранены в: {graph_path}")
|
||||
|
||||
return graph_path
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
results, docs_dir = run_experiment()
|
||||
|
||||
|
||||
try:
|
||||
graph_file = create_graphs(results, docs_dir)
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("ЭКСПЕРИМЕНТ ЗАВЕРШЕН УСПЕШНО!")
|
||||
print("=" * 70)
|
||||
print("\nСОЗДАННЫЕ ФАЙЛЫ:")
|
||||
print(f" Данные: {os.path.join(docs_dir, 'experiment_results.csv')}")
|
||||
print(f" Графики: {graph_file}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\nОшибка при построении графиков: {e}")
|
||||
print(" Убедитесь, что установлен matplotlib: pip install matplotlib")
|
||||
print("\n" + "=" * 70)
|
||||
print("ЭКСПЕРИМЕНТ ЗАВЕРШЕН (без графиков)")
|
||||
print("=" * 70)
|
||||
print(f"\nCSV файл сохранен: {os.path.join(docs_dir, 'experiment_results.csv')}")
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
Структура,Режим,Операция,Замер1(с),Замер2(с),Замер3(с),Замер4(с),Замер5(с),Среднее(с)
|
||||
linked_list,случайный,вставка,11.072574299992993,12.38099840003997,12.155311000009533,12.81002289999742,13.201067199988756,12.323994760005736
|
||||
linked_list,случайный,поиск,0.1209169999929145,0.13400630000978708,0.1302103999769315,0.12179599999217317,0.13267739996081218,0.12792141998652368
|
||||
linked_list,случайный,удаление,0.05278969998471439,0.05019940005149692,0.05289009999250993,0.0488043999648653,0.061356800026260316,0.05320808000396937
|
||||
hash_table,случайный,вставка,0.694432099990081,0.7192347000236623,0.7134853000170551,0.6891152000171132,0.6973775000078604,0.7027289600111544
|
||||
hash_table,случайный,поиск,0.006584499962627888,0.004749000014271587,0.004359900020062923,0.006477299961261451,0.006112299975939095,0.005656599986832589
|
||||
hash_table,случайный,удаление,0.004070399969350547,0.004140400036703795,0.003542299964465201,0.0032371999695897102,0.0030583000043407083,0.0036097199888899924
|
||||
bst,случайный,вставка,0.08137199998600408,0.08989329996984452,0.08159760001581162,0.07841239997651428,0.1001471999916248,0.08628449998795987
|
||||
bst,случайный,поиск,0.0006561999907717109,0.00043180002830922604,0.00042429997120052576,0.0004227000172249973,0.00043509999522939324,0.0004740200005471706
|
||||
bst,случайный,удаление,0.19723930000327528,0.166880399978254,0.147482400003355,0.18100009998306632,0.16498840000713244,0.1715181199950166
|
||||
linked_list,отсортированный,вставка,12.294058899977244,11.597062399960123,11.59195000003092,11.623520500026643,11.401553199975751,11.701628999994137
|
||||
linked_list,отсортированный,поиск,0.10066379996715114,0.0991929000010714,0.09696789999725297,0.09909789997618645,0.09873830003198236,0.09893215999472886
|
||||
linked_list,отсортированный,удаление,0.05669830000260845,0.048193000024184585,0.05076910002389923,0.04920080001465976,0.05905079998774454,0.05278240001061931
|
||||
hash_table,отсортированный,вставка,0.5518350999918766,0.5407364999991842,0.5291212999727577,0.5373308000271209,0.529426000022795,0.5376899400027468
|
||||
hash_table,отсортированный,поиск,0.005108800018206239,0.004848999960813671,0.004103399987798184,0.0038874000310897827,0.005848900007549673,0.00475950000109151
|
||||
hash_table,отсортированный,удаление,0.0037329999613575637,0.003185699984896928,0.0028516000020317733,0.0030229000258259475,0.0037879000301472843,0.003316220000851899
|
||||
bst,отсортированный,вставка,32.23637629998848,33.77348939998774,33.518200399994384,33.78866110002855,33.55791890004184,33.3749292200082
|
||||
bst,отсортированный,поиск,0.1479294000309892,0.1305704999831505,0.13548930000979453,0.1314462999580428,0.130273999995552,0.1351418999955058
|
||||
bst,отсортированный,удаление,0.1574716999894008,0.16461069998331368,0.15460990002611652,0.15385339997010306,0.15677610004786402,0.15746436000335962
|
||||
|
Binary file not shown.
|
Before Width: | Height: | Size: 117 KiB |
|
|
@ -1,73 +0,0 @@
|
|||
# Отчёт: Задание 1 — Структуры данных
|
||||
|
||||
## Цель работы
|
||||
|
||||
Реализовать три структуры данных «с нуля» в процедурной парадигме (без классов), применить их для хранения записей телефонного справочника и экспериментально сравнить производительность основных операций.
|
||||
|
||||
## Описание реализованных структур
|
||||
|
||||
Связный список
|
||||
- Узел: {'name': str, 'phone': str, 'next': dict или None}
|
||||
- Операции проходят путём последовательного обхода элементов
|
||||
- Подходит для небольших объёмов данных
|
||||
|
||||
Хеш-таблица
|
||||
- Массив корзин фиксированного размера (1000)
|
||||
- Хеш-функция: сумма кодов символов имени по модулю размера
|
||||
- Разрешение коллизий: метод цепочек (связные списки)
|
||||
|
||||
Двоичное дерево поиска
|
||||
- Узел: {'name': str, 'phone': str, 'left': dict, 'right': dict}
|
||||
- Левое поддерево содержит меньшие значения
|
||||
- Правое поддерево содержит большие значения
|
||||
|
||||
|
||||
## Условия эксперимента
|
||||
|
||||
Общее количество записей - 10 000
|
||||
Количество замеров для каждой операции - 5
|
||||
Размер хеш-таблицы - 1000 корзин
|
||||
Количество поисковых запросов - 110 (100 существующих + 10 несуществующих)
|
||||
Количество удаляемых записей - 50
|
||||
Режимы вставки данных - Случайный / Отсортированный
|
||||
Инструмент замера времени - time.perf_counter()
|
||||
|
||||
|
||||
## Результаты
|
||||
|
||||
### Таблица средних времён (секунды)
|
||||
|
||||
| Структура | Режим | Вставка (с) | Поиск 110 (с) | Удаление 50 (с) |
|
||||
|---|---|---|---|---|
|
||||
| LinkedList | случайный | 12.32399 | 0.1279214 | 0.053208 |
|
||||
| LinkedList | сортированный | 11.701628 | 0.0989321 | 0.052782 |
|
||||
| HashTable | случайный | 0.7027289 | 0.0056565 | 0.0036097 |
|
||||
| HashTable | сортированный | 0.5376899 | 0.0047595 | 0.003316 |
|
||||
| BST | случайный | 0.08628449 | 0.000474 | 0.1715181 |
|
||||
| BST | сортированный | 33.374929 | 0.1351418 | 0.1574643 |
|
||||
|
||||
### Графики
|
||||
|
||||

|
||||
|
||||
## Анализ результатов
|
||||
|
||||
### Связный список
|
||||
|
||||
Вставка в список занимает ~2.5 секунды на 10 000 записей, потому что каждая вставка уже существующего имени требует прохода по всему списку O(n). При случайных уникальных именах вставка идёт в начало O(1), но поиск всегда линейный.
|
||||
|
||||
### Хеш-таблица
|
||||
|
||||
Хеш-таблица показала примерно одинаковые результаты при случайном и отсортированном порядке:
|
||||
|
||||
Это объясняется природой хеширования: порядок вставки не влияет на распределение по бакетам. Ключ всегда попадает в предсказуемый бакет за O(1).
|
||||
|
||||
### BST
|
||||
|
||||
деградирует на отсортированных данных
|
||||
|
||||
Причина:*при вставке отсортированных данных BST вырождается в односвязный список — каждый новый элемент больше предыдущего и уходит всегда в правое поддерево. Высота дерева становится O(n) вместо O(log n). Поиск и удаление тоже деградируют до O(n).
|
||||
|
||||
## Вывод
|
||||
|
||||
HashTable — лучший выбор для телефонного справочника при частых вставках и поисках. BST лучше HashTable только если нужен отсортированный вывод без дополнительной сортировки — но при условии случайного порядка вставки или использования самобалансирующегося дерева (AVL, Red-Black).
|
||||
Loading…
Reference in New Issue
Block a user