forked from UNN/2026-rff_mp
[1] firstex
This commit is contained in:
parent
aa6fbb0692
commit
da3cf034d1
212
ZhuravlevDV/docs/data/firstex/LinkedListPhoneBook.py
Normal file
212
ZhuravlevDV/docs/data/firstex/LinkedListPhoneBook.py
Normal file
|
|
@ -0,0 +1,212 @@
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
import csv
|
||||||
|
|
||||||
|
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']:
|
||||||
|
current = current['next']
|
||||||
|
current['next'] = new_node
|
||||||
|
return head
|
||||||
|
|
||||||
|
def ll_find(head, name):
|
||||||
|
current = head
|
||||||
|
while current:
|
||||||
|
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']:
|
||||||
|
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:
|
||||||
|
records.append((current['name'], current['phone']))
|
||||||
|
current = current['next']
|
||||||
|
records.sort(key=lambda x: x[0])
|
||||||
|
return records
|
||||||
|
|
||||||
|
def ht_insert(buckets, name, phone):
|
||||||
|
index = hash(name) % len(buckets)
|
||||||
|
buckets[index] = ll_insert(buckets[index], name, phone)
|
||||||
|
return buckets
|
||||||
|
|
||||||
|
def ht_find(buckets, name):
|
||||||
|
index = hash(name) % len(buckets)
|
||||||
|
return ll_find(buckets[index], name)
|
||||||
|
|
||||||
|
def ht_delete(buckets, name):
|
||||||
|
index = hash(name) % len(buckets)
|
||||||
|
buckets[index] = ll_delete(buckets[index], name)
|
||||||
|
return buckets
|
||||||
|
|
||||||
|
def ht_list_all(buckets):
|
||||||
|
records = []
|
||||||
|
for bucket in buckets:
|
||||||
|
current = bucket
|
||||||
|
while current:
|
||||||
|
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):
|
||||||
|
if root is None:
|
||||||
|
return None
|
||||||
|
if name == root['name']:
|
||||||
|
return root['phone']
|
||||||
|
elif name < root['name']:
|
||||||
|
return bst_find(root['left'], name)
|
||||||
|
else:
|
||||||
|
return bst_find(root['right'], name)
|
||||||
|
|
||||||
|
def bst_min_node(node):
|
||||||
|
current = node
|
||||||
|
while current['left']:
|
||||||
|
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']
|
||||||
|
temp = bst_min_node(root['right'])
|
||||||
|
root['name'] = temp['name']
|
||||||
|
root['phone'] = temp['phone']
|
||||||
|
root['right'] = bst_delete(root['right'], temp['name'])
|
||||||
|
return root
|
||||||
|
|
||||||
|
def bst_list_all(root):
|
||||||
|
records = []
|
||||||
|
if root:
|
||||||
|
records.extend(bst_list_all(root['left']))
|
||||||
|
records.append((root['name'], root['phone']))
|
||||||
|
records.extend(bst_list_all(root['right']))
|
||||||
|
return records
|
||||||
|
|
||||||
|
def generate_records(n):
|
||||||
|
records = [(f"User_{i:05d}", f"+7-999-{i:07d}") for i in range(n)]
|
||||||
|
records_shuffled = records.copy()
|
||||||
|
random.shuffle(records_shuffled)
|
||||||
|
records_sorted = sorted(records, key=lambda x: x[0])
|
||||||
|
return records_shuffled, records_sorted
|
||||||
|
|
||||||
|
def run_experiment(structure_name, records, insert_func, find_func, delete_func, list_all_func, buckets=None):
|
||||||
|
if structure_name == "HashTable":
|
||||||
|
buckets = [None] * 1000
|
||||||
|
|
||||||
|
start = time.perf_counter()
|
||||||
|
if structure_name == "HashTable":
|
||||||
|
for name, phone in records:
|
||||||
|
buckets = insert_func(buckets, name, phone)
|
||||||
|
else:
|
||||||
|
root_or_head = None
|
||||||
|
for name, phone in records:
|
||||||
|
if structure_name == "LinkedList":
|
||||||
|
root_or_head = insert_func(root_or_head, name, phone)
|
||||||
|
else:
|
||||||
|
root_or_head = insert_func(root_or_head, name, phone)
|
||||||
|
insert_time = time.perf_counter() - start
|
||||||
|
|
||||||
|
existing_names = [name for name, _ in records[:100]]
|
||||||
|
nonexisting_names = [f"None_{i}" for i in range(10)]
|
||||||
|
all_searches = existing_names + nonexisting_names
|
||||||
|
random.shuffle(all_searches)
|
||||||
|
|
||||||
|
start = time.perf_counter()
|
||||||
|
for name in all_searches:
|
||||||
|
if structure_name == "HashTable":
|
||||||
|
find_func(buckets, name)
|
||||||
|
else:
|
||||||
|
find_func(root_or_head, name)
|
||||||
|
find_time = time.perf_counter() - start
|
||||||
|
|
||||||
|
delete_names = [records[i][0] for i in random.sample(range(len(records)), min(50, len(records)))]
|
||||||
|
start = time.perf_counter()
|
||||||
|
for name in delete_names:
|
||||||
|
if structure_name == "HashTable":
|
||||||
|
buckets = delete_func(buckets, name)
|
||||||
|
else:
|
||||||
|
root_or_head = delete_func(root_or_head, name)
|
||||||
|
delete_time = time.perf_counter() - start
|
||||||
|
|
||||||
|
return insert_time, find_time, delete_time
|
||||||
|
|
||||||
|
def main():
|
||||||
|
N = 1000
|
||||||
|
records_shuffled, records_sorted = generate_records(N)
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
for mode, records in [("случайный", records_shuffled), ("отсортированный", records_sorted)]:
|
||||||
|
for run in range(5):
|
||||||
|
ins_ll, find_ll, del_ll = run_experiment("LinkedList", records, ll_insert, ll_find, ll_delete, ll_list_all)
|
||||||
|
results.append(["LinkedList", mode, "вставка", ins_ll, run+1])
|
||||||
|
results.append(["LinkedList", mode, "поиск", find_ll, run+1])
|
||||||
|
results.append(["LinkedList", mode, "удаление", del_ll, run+1])
|
||||||
|
|
||||||
|
ins_ht, find_ht, del_ht = run_experiment("HashTable", records, ht_insert, ht_find, ht_delete, ht_list_all)
|
||||||
|
results.append(["HashTable", mode, "вставка", ins_ht, run+1])
|
||||||
|
results.append(["HashTable", mode, "поиск", find_ht, run+1])
|
||||||
|
results.append(["HashTable", mode, "удаление", del_ht, run+1])
|
||||||
|
|
||||||
|
ins_bst, find_bst, del_bst = run_experiment("BST", records, bst_insert, bst_find, bst_delete, bst_list_all)
|
||||||
|
results.append(["BST", mode, "вставка", ins_bst, run+1])
|
||||||
|
results.append(["BST", mode, "поиск", find_bst, run+1])
|
||||||
|
results.append(["BST", mode, "удаление", del_bst, run+1])
|
||||||
|
|
||||||
|
with open("results.csv", "w", newline="", encoding="utf-8") as f:
|
||||||
|
writer = csv.writer(f)
|
||||||
|
writer.writerow(["Структура", "Режим", "Операция", "Время (сек)", "Повторение"])
|
||||||
|
writer.writerows(results)
|
||||||
|
|
||||||
|
avg_results = {}
|
||||||
|
for row in results:
|
||||||
|
key = (row[0], row[1], row[2])
|
||||||
|
if key not in avg_results:
|
||||||
|
avg_results[key] = []
|
||||||
|
avg_results[key].append(row[3])
|
||||||
|
|
||||||
|
with open("avg_results.csv", "w", newline="", encoding="utf-8") as f:
|
||||||
|
writer = csv.writer(f)
|
||||||
|
writer.writerow(["Структура", "Режим", "Операция", "Среднее время (сек)"])
|
||||||
|
for (struct, mode, op), times in avg_results.items():
|
||||||
|
writer.writerow([struct, mode, op, sum(times)/len(times)])
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Reference in New Issue
Block a user