2026-rff_mp/meosyam/docs/data/1/phonebook.py

248 lines
6.6 KiB
Python

def ll_insert(head, name, phone):
cur = head
while cur:
if cur['name'] == name:
cur['phone'] = phone
return head
cur = cur['next']
new_node = {'name': name, 'phone': phone, 'next': None}
if head is None:
return new_node
cur = head
while cur['next']:
cur = cur['next']
cur['next'] = new_node
return head
def ll_find(head, name):
cur = head
while cur:
if cur['name'] == name:
return cur['phone']
cur = cur['next']
return None
def ll_delete(head, name):
if head is None:
return None
if head['name'] == name:
return head['next']
prev = head
cur = head['next']
while cur:
if cur['name'] == name:
prev['next'] = cur['next']
return head
prev = cur
cur = cur['next']
return head
def ll_list_all(head):
res = []
cur = head
while cur:
res.append((cur['name'], cur['phone']))
cur = cur['next']
res.sort(key=lambda x: x[0])
return res
SIZE = 5
def hash_func(name):
s = 0
for ch in name:
s += ord(ch)
return s % SIZE
def ht_insert(buckets, name, phone):
idx = hash_func(name)
buckets[idx] = ll_insert(buckets[idx], name, phone)
return buckets
def ht_find(buckets, name):
idx = hash_func(name)
return ll_find(buckets[idx], name)
def ht_delete(buckets, name):
idx = hash_func(name)
buckets[idx] = ll_delete(buckets[idx], name)
return buckets
def ht_list_all(buckets):
all_rec = []
for head in buckets:
cur = head
while cur:
all_rec.append((cur['name'], cur['phone']))
cur = cur['next']
all_rec.sort(key=lambda x: x[0])
return all_rec
def create_node(name, phone):
return {'name': name, 'phone': phone, 'left': None, 'right': None}
def bst_insert(root, name, phone):
if root is None:
return create_node(name, phone)
cur = root
while True:
if name == cur['name']:
cur['phone'] = phone
return root
elif name < cur['name']:
if cur['left'] is None:
cur['left'] = create_node(name, phone)
return root
cur = cur['left']
else:
if cur['right'] is None:
cur['right'] = create_node(name, phone)
return root
cur = cur['right']
def bst_find(root, name):
cur = root
while cur:
if name == cur['name']:
return cur['phone']
elif name < cur['name']:
cur = cur['left']
else:
cur = cur['right']
return None
def find_min(node):
while node['left']:
node = node['left']
return node
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']
if root['right'] is None:
return root['left']
mn = find_min(root['right'])
root['name'] = mn['name']
root['phone'] = mn['phone']
root['right'] = bst_delete(root['right'], mn['name'])
return root
def bst_list_all(root):
res = []
def inorder(node):
if node:
inorder(node['left'])
res.append((node['name'], node['phone']))
inorder(node['right'])
inorder(root)
return res
import random, time, csv, sys
sys.setrecursionlimit(20000)
def generate_records(n, seed=42):
random.seed(seed)
rec = []
for i in range(1, n+1):
name = f"User_{i:05d}"
phone = f"{random.randint(100,999)}-{random.randint(1000,9999)}"
rec.append((name, phone))
return rec
def prepare_datasets(base):
shuffled = base.copy()
random.shuffle(shuffled)
sorted_rec = sorted(base, key=lambda x: x[0])
return shuffled, sorted_rec
def run_experiment(funcs, records, mode, repeats=3):
results = []
for rep in range(repeats):
struct = funcs['create']()
t0 = time.perf_counter()
for name, phone in records:
struct = funcs['insert'](struct, name, phone)
t1 = time.perf_counter()
ins = t1 - t0
existing = [n for n, _ in records]
sample = random.sample(existing, 100)
non_ex = [f"None_{i}" for i in range(10)]
to_search = sample + non_ex
random.shuffle(to_search)
t0 = time.perf_counter()
for name in to_search:
_ = funcs['find'](struct, name)
t1 = time.perf_counter()
find_t = t1 - t0
to_del = random.sample(existing, 10)
t0 = time.perf_counter()
for name in to_del:
struct = funcs['delete'](struct, name)
t1 = time.perf_counter()
del_t = t1 - t0
results.append({
'structure': funcs['name'],
'mode': mode,
'rep': rep+1,
'insert': ins,
'search': find_t,
'delete': del_t
})
return results
def main():
N = 1000
base = generate_records(N)
shuffled, sorted_rec = prepare_datasets(base)
structs = {
'LinkedList': {
'name': 'LinkedList',
'create': lambda: None,
'insert': ll_insert,
'find': ll_find,
'delete': ll_delete,
'list_all': ll_list_all
},
'HashTable': {
'name': 'HashTable',
'create': lambda: [None] * SIZE,
'insert': ht_insert,
'find': ht_find,
'delete': ht_delete,
'list_all': ht_list_all
},
'BST': {
'name': 'BST',
'create': lambda: None,
'insert': bst_insert,
'find': bst_find,
'delete': bst_delete,
'list_all': bst_list_all
}
}
all_res = []
for name, funcs in structs.items():
print(f"Testing {name} random...")
all_res += run_experiment(funcs, shuffled, 'random')
print(f"Testing {name} sorted...")
all_res += run_experiment(funcs, sorted_rec, 'sorted')
with open('results.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['Structure','Mode','Repeat','Insert','Search','Delete'])
for r in all_res:
writer.writerow([r['structure'], r['mode'], r['rep'],
f"{r['insert']:.6f}", f"{r['search']:.6f}", f"{r['delete']:.6f}"])
print("Done. Results in results.csv")
if __name__ == '__main__':
main()