[1] data structures #248
0
VildyaevAV/docs/report.md
Normal file
0
VildyaevAV/docs/report.md
Normal file
19
VildyaevAV/results.csv
Normal file
19
VildyaevAV/results.csv
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Structure,Mode,Operation,Time
|
||||
LinkedList,random,insert,2.179811800000607
|
||||
LinkedList,random,find,0.019349800000782125
|
||||
LinkedList,random,delete,0.01508280000052764
|
||||
LinkedList,sorted,insert,1.7312419000008958
|
||||
LinkedList,sorted,find,0.01827670000056969
|
||||
LinkedList,sorted,delete,0.01452439999775379
|
||||
HashTable,random,insert,0.13504540000212728
|
||||
HashTable,random,find,0.0014485000028798822
|
||||
HashTable,random,delete,0.0010058999978355132
|
||||
HashTable,sorted,insert,0.12148510000042734
|
||||
HashTable,sorted,find,0.0012095999991288409
|
||||
HashTable,sorted,delete,0.0008018999978958163
|
||||
BST,random,insert,0.016409800002293196
|
||||
BST,random,find,0.0001536999989184551
|
||||
BST,random,delete,9.40000027185306e-05
|
||||
BST,sorted,insert,15.077545899999677
|
||||
BST,sorted,find,0.05779409999740892
|
||||
BST,sorted,delete,0.03522280000106548
|
||||
|
345
VildyaevAV/task1.py
Normal file
345
VildyaevAV/task1.py
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
import random
|
||||
import time
|
||||
import csv
|
||||
import sys
|
||||
sys.setrecursionlimit(30000)
|
||||
|
||||
|
||||
# =========================
|
||||
# LINKED LIST
|
||||
# =========================
|
||||
|
||||
def ll_insert(head, name, phone):
|
||||
current = head
|
||||
|
||||
while current:
|
||||
if current["name"] == name:
|
||||
current["phone"] = phone
|
||||
return head
|
||||
current = current["next"]
|
||||
|
||||
new_node = {
|
||||
"name": name,
|
||||
"phone": phone,
|
||||
"next": head
|
||||
}
|
||||
|
||||
return new_node
|
||||
|
||||
|
||||
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):
|
||||
result = []
|
||||
|
||||
current = head
|
||||
|
||||
while current:
|
||||
result.append((current["name"], current["phone"]))
|
||||
current = current["next"]
|
||||
|
||||
return sorted(result)
|
||||
|
||||
|
||||
# =========================
|
||||
# HASH TABLE
|
||||
# =========================
|
||||
|
||||
TABLE_SIZE = 1000
|
||||
|
||||
|
||||
def hash_func(name):
|
||||
return sum(ord(c) for c in name) % TABLE_SIZE
|
||||
|
||||
|
||||
def ht_insert(buckets, name, phone):
|
||||
index = hash_func(name)
|
||||
buckets[index] = ll_insert(buckets[index], name, phone)
|
||||
|
||||
|
||||
def ht_find(buckets, name):
|
||||
index = hash_func(name)
|
||||
return ll_find(buckets[index], name)
|
||||
|
||||
|
||||
def ht_delete(buckets, name):
|
||||
index = hash_func(name)
|
||||
buckets[index] = ll_delete(buckets[index], name)
|
||||
|
||||
|
||||
def ht_list_all(buckets):
|
||||
result = []
|
||||
|
||||
for bucket in buckets:
|
||||
result.extend(ll_list_all(bucket))
|
||||
|
||||
return sorted(result)
|
||||
|
||||
|
||||
# =========================
|
||||
# BST
|
||||
# =========================
|
||||
|
||||
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"]
|
||||
|
||||
if name < root["name"]:
|
||||
return bst_find(root["left"], name)
|
||||
|
||||
return bst_find(root["right"], name)
|
||||
|
||||
|
||||
def bst_min(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"]
|
||||
|
||||
if root["right"] is None:
|
||||
return root["left"]
|
||||
|
||||
temp = bst_min(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):
|
||||
if root is None:
|
||||
return []
|
||||
|
||||
return (
|
||||
bst_list_all(root["left"])
|
||||
+ [(root["name"], root["phone"])]
|
||||
+ bst_list_all(root["right"])
|
||||
)
|
||||
|
||||
|
||||
# =========================
|
||||
# TEST DATA
|
||||
# =========================
|
||||
|
||||
N = 10000
|
||||
|
||||
records = [
|
||||
(f"User_{i:05d}", str(random.randint(100000, 999999)))
|
||||
for i in range(N)
|
||||
]
|
||||
|
||||
records_shuffled = records[:]
|
||||
random.shuffle(records_shuffled)
|
||||
|
||||
records_sorted = sorted(records)
|
||||
|
||||
|
||||
# =========================
|
||||
# BENCHMARK
|
||||
# =========================
|
||||
|
||||
results = [
|
||||
["Structure", "Mode", "Operation", "Time"]
|
||||
]
|
||||
|
||||
|
||||
def benchmark_linked_list(records_input, mode):
|
||||
global results
|
||||
|
||||
head = None
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name, phone in records_input:
|
||||
head = ll_insert(head, name, phone)
|
||||
|
||||
end = time.perf_counter()
|
||||
|
||||
results.append(["LinkedList", mode, "insert", end - start])
|
||||
|
||||
sample = random.sample(records_input, 100)
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name, _ in sample:
|
||||
ll_find(head, name)
|
||||
|
||||
end = time.perf_counter()
|
||||
|
||||
results.append(["LinkedList", mode, "find", end - start])
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name, _ in sample[:50]:
|
||||
head = ll_delete(head, name)
|
||||
|
||||
end = time.perf_counter()
|
||||
|
||||
results.append(["LinkedList", mode, "delete", end - start])
|
||||
|
||||
|
||||
def benchmark_hash_table(records_input, mode):
|
||||
global results
|
||||
|
||||
buckets = [None] * TABLE_SIZE
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name, phone in records_input:
|
||||
ht_insert(buckets, name, phone)
|
||||
|
||||
end = time.perf_counter()
|
||||
|
||||
results.append(["HashTable", mode, "insert", end - start])
|
||||
|
||||
sample = random.sample(records_input, 100)
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name, _ in sample:
|
||||
ht_find(buckets, name)
|
||||
|
||||
end = time.perf_counter()
|
||||
|
||||
results.append(["HashTable", mode, "find", end - start])
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name, _ in sample[:50]:
|
||||
ht_delete(buckets, name)
|
||||
|
||||
end = time.perf_counter()
|
||||
|
||||
results.append(["HashTable", mode, "delete", end - start])
|
||||
|
||||
|
||||
def benchmark_bst(records_input, mode):
|
||||
global results
|
||||
|
||||
root = None
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name, phone in records_input:
|
||||
root = bst_insert(root, name, phone)
|
||||
|
||||
end = time.perf_counter()
|
||||
|
||||
results.append(["BST", mode, "insert", end - start])
|
||||
|
||||
sample = random.sample(records_input, 100)
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name, _ in sample:
|
||||
bst_find(root, name)
|
||||
|
||||
end = time.perf_counter()
|
||||
|
||||
results.append(["BST", mode, "find", end - start])
|
||||
|
||||
start = time.perf_counter()
|
||||
|
||||
for name, _ in sample[:50]:
|
||||
root = bst_delete(root, name)
|
||||
|
||||
end = time.perf_counter()
|
||||
|
||||
results.append(["BST", mode, "delete", end - start])
|
||||
|
||||
|
||||
# =========================
|
||||
# RUN TESTS
|
||||
# =========================
|
||||
|
||||
benchmark_linked_list(records_shuffled, "random")
|
||||
benchmark_linked_list(records_sorted, "sorted")
|
||||
|
||||
benchmark_hash_table(records_shuffled, "random")
|
||||
benchmark_hash_table(records_sorted, "sorted")
|
||||
|
||||
benchmark_bst(records_shuffled, "random")
|
||||
benchmark_bst(records_sorted, "sorted")
|
||||
|
||||
|
||||
# =========================
|
||||
# SAVE CSV
|
||||
# =========================
|
||||
|
||||
with open("results.csv", "w", newline="") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerows(results)
|
||||
|
||||
print("Done! Results saved to results.csv")
|
||||
Loading…
Reference in New Issue
Block a user