From 6b73e194fd392a16eef323ddcbdce4d1e1ae6ee9 Mon Sep 17 00:00:00 2001 From: meosyam Date: Thu, 3 Sep 2026 12:54:57 +0000 Subject: [PATCH] [1] add BST and experiment --- meosyam/docs/data/1/phonebook.py | 176 +++++++++++++++++++++++++++++-- 1 file changed, 167 insertions(+), 9 deletions(-) diff --git a/meosyam/docs/data/1/phonebook.py b/meosyam/docs/data/1/phonebook.py index d04fe1b..e16dd5c 100644 --- a/meosyam/docs/data/1/phonebook.py +++ b/meosyam/docs/data/1/phonebook.py @@ -78,13 +78,171 @@ def ht_list_all(buckets): 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__': - buckets = [None] * SIZE - ht_insert(buckets, '1', '123-456') - ht_insert(buckets, '2', '789-012') - ht_insert(buckets, '3', '345-678') - ht_insert(buckets, '4', '111-222') - print("HT all:", ht_list_all(buckets)) - print("HT find 1:", ht_find(buckets, '1')) - ht_delete(buckets, '2') - print("HT after delete 2:", ht_list_all(buckets)) \ No newline at end of file + main() \ No newline at end of file