forked from UNN/2026-rff_mp
Compare commits
5 Commits
29f33fa407
...
a95db6edf3
| Author | SHA1 | Date | |
|---|---|---|---|
| a95db6edf3 | |||
| 516ac2e1fb | |||
| df10b20f41 | |||
| 8963a00e6e | |||
| 77c787c2f4 |
193
VolkovVA/cod.py
193
VolkovVA/cod.py
|
|
@ -1,4 +1,8 @@
|
||||||
import random as rnd
|
import random as rnd
|
||||||
|
import time
|
||||||
|
import csv
|
||||||
|
|
||||||
|
# СВЯЗНЫЙ СПИСОК
|
||||||
|
|
||||||
|
|
||||||
def ll_insert(head, name, phone):
|
def ll_insert(head, name, phone):
|
||||||
|
|
@ -6,8 +10,7 @@ def ll_insert(head, name, phone):
|
||||||
|
|
||||||
if head is None:
|
if head is None:
|
||||||
return new_node
|
return new_node
|
||||||
|
|
||||||
|
|
||||||
current = head
|
current = head
|
||||||
while current is not None:
|
while current is not None:
|
||||||
if current['name'] == name:
|
if current['name'] == name:
|
||||||
|
|
@ -21,6 +24,7 @@ def ll_insert(head, name, phone):
|
||||||
return head
|
return head
|
||||||
|
|
||||||
def ll_find(head, name):
|
def ll_find(head, name):
|
||||||
|
|
||||||
current = head
|
current = head
|
||||||
while current is not None:
|
while current is not None:
|
||||||
if current['name'] == name:
|
if current['name'] == name:
|
||||||
|
|
@ -28,8 +32,8 @@ def ll_find(head, name):
|
||||||
current = current['next']
|
current = current['next']
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def ll_delete(head, name):
|
def ll_delete(head, name):
|
||||||
|
|
||||||
if head is None:
|
if head is None:
|
||||||
return None
|
return None
|
||||||
if head['name'] == name:
|
if head['name'] == name:
|
||||||
|
|
@ -43,8 +47,8 @@ def ll_delete(head, name):
|
||||||
current = current['next']
|
current = current['next']
|
||||||
return head
|
return head
|
||||||
|
|
||||||
|
|
||||||
def sort_records(lst):
|
def sort_records(lst):
|
||||||
|
|
||||||
n = len(lst)
|
n = len(lst)
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
for j in range(0, n-i-1):
|
for j in range(0, n-i-1):
|
||||||
|
|
@ -52,7 +56,6 @@ def sort_records(lst):
|
||||||
lst[j], lst[j + 1] = lst[j + 1], lst[j]
|
lst[j], lst[j + 1] = lst[j + 1], lst[j]
|
||||||
return lst
|
return lst
|
||||||
|
|
||||||
|
|
||||||
def ll_list_all(head):
|
def ll_list_all(head):
|
||||||
record = []
|
record = []
|
||||||
current = head
|
current = head
|
||||||
|
|
@ -63,36 +66,33 @@ def ll_list_all(head):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
# ХЕШ-ТАБЛИЦА
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def def_hash(name, size):
|
def def_hash(name, size):
|
||||||
|
|
||||||
hash_value = 0
|
hash_value = 0
|
||||||
for char in name:
|
for char in name:
|
||||||
hash_value += ord(char)
|
hash_value += ord(char)
|
||||||
final_idx = hash_value % size
|
final_idx = hash_value % size
|
||||||
return final_idx
|
return final_idx
|
||||||
|
|
||||||
|
|
||||||
def ht_insert(buckets, name, phone):
|
def ht_insert(buckets, name, phone):
|
||||||
size = len(buckets)
|
size = len(buckets)
|
||||||
idx = def_hash(name, size)
|
idx = def_hash(name, size)
|
||||||
ll_insert(buckets[idx], name, phone)
|
buckets[idx] = ll_insert(buckets[idx], name, phone)
|
||||||
|
return buckets
|
||||||
|
|
||||||
def ht_find(buckets, name):
|
def ht_find(buckets, name):
|
||||||
size = len(buckets)
|
size = len(buckets)
|
||||||
idx = def_hash(name, size)
|
idx = def_hash(name, size)
|
||||||
return ll_find(buckets[idx], name)
|
return ll_find(buckets[idx], name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def ht_delete(buckets, name):
|
def ht_delete(buckets, name):
|
||||||
size = len(buckets)
|
size = len(buckets)
|
||||||
idx = def_hash(name, size)
|
idx = def_hash(name, size)
|
||||||
buckets[idx] = ll_delete(buckets[idx], name)
|
buckets[idx] = ll_delete(buckets[idx], name)
|
||||||
|
return buckets
|
||||||
|
|
||||||
def ht_list_all(buckets):
|
def ht_list_all(buckets):
|
||||||
res = []
|
res = []
|
||||||
|
|
@ -104,7 +104,7 @@ def ht_list_all(buckets):
|
||||||
return sort_records(res)
|
return sort_records(res)
|
||||||
|
|
||||||
|
|
||||||
|
# ДВОИЧНОЕ ДЕРЕВО ПОИСКА
|
||||||
|
|
||||||
|
|
||||||
def bst_insert(root, name, phone):
|
def bst_insert(root, name, phone):
|
||||||
|
|
@ -131,7 +131,6 @@ def bst_insert(root, name, phone):
|
||||||
|
|
||||||
return root
|
return root
|
||||||
|
|
||||||
|
|
||||||
def bst_find(root, name):
|
def bst_find(root, name):
|
||||||
current = root
|
current = root
|
||||||
while current is not None:
|
while current is not None:
|
||||||
|
|
@ -143,7 +142,6 @@ def bst_find(root, name):
|
||||||
current = current['right']
|
current = current['right']
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def bst_delete(root, name):
|
def bst_delete(root, name):
|
||||||
if root is None:
|
if root is None:
|
||||||
return None
|
return None
|
||||||
|
|
@ -197,7 +195,6 @@ def bst_delete(root, name):
|
||||||
p_node['right'] = c_node
|
p_node['right'] = c_node
|
||||||
return root
|
return root
|
||||||
|
|
||||||
|
|
||||||
def bst_list_all(root):
|
def bst_list_all(root):
|
||||||
record = []
|
record = []
|
||||||
|
|
||||||
|
|
@ -209,4 +206,164 @@ def bst_list_all(root):
|
||||||
helper(node['right'])
|
helper(node['right'])
|
||||||
|
|
||||||
helper(root)
|
helper(root)
|
||||||
return record
|
return record
|
||||||
|
|
||||||
|
|
||||||
|
# ЭКСПЕРИМЕНТАЛЬНАЯ ЧАСТЬ
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
N = 10000
|
||||||
|
|
||||||
|
|
||||||
|
records = []
|
||||||
|
for i in range(N):
|
||||||
|
name = f"User_{i:05d}"
|
||||||
|
phone = f"+7-{rnd.randint(100, 999)}-{rnd.randint(100, 999)}-{rnd.randint(1000, 9999)}"
|
||||||
|
records.append((name, phone))
|
||||||
|
|
||||||
|
|
||||||
|
records_shuffled = records[:]
|
||||||
|
rnd.shuffle(records_shuffled)
|
||||||
|
records_sorted = sorted(records, key=lambda x: x[0])
|
||||||
|
|
||||||
|
|
||||||
|
s_names = []
|
||||||
|
for i in range(100):
|
||||||
|
s_names.append(records_shuffled[i][0])
|
||||||
|
for i in range(10):
|
||||||
|
s_names.append(f"None_{i}")
|
||||||
|
|
||||||
|
d_names = []
|
||||||
|
sampled = rnd.sample(records_shuffled, 50)
|
||||||
|
for item in sampled:
|
||||||
|
d_names.append(item[0])
|
||||||
|
|
||||||
|
print("Начало замеров...")
|
||||||
|
|
||||||
|
results = [["Структура", "Режим", "Операция", "Время (сек)"]]
|
||||||
|
|
||||||
|
|
||||||
|
# ПРОВЕДЕНИЕ ЗАМЕРОВ
|
||||||
|
|
||||||
|
# СВЯЗНЫЙ СПИСОК
|
||||||
|
for mode_name, data in [("случайный", records_shuffled), ("отсортированный", records_sorted)]:
|
||||||
|
s_ins = 0
|
||||||
|
s_fnd=0
|
||||||
|
s_del=0
|
||||||
|
for _ in range(5):
|
||||||
|
ll = None
|
||||||
|
|
||||||
|
|
||||||
|
t1 = time.perf_counter()
|
||||||
|
for name, phone in data:
|
||||||
|
ll = ll_insert(ll, name, phone)
|
||||||
|
time_ins = time.perf_counter() - t1
|
||||||
|
s_ins += time_ins
|
||||||
|
results.append(["LinkedList", mode_name, "вставка", time_ins])
|
||||||
|
|
||||||
|
|
||||||
|
t1 = time.perf_counter()
|
||||||
|
for name in s_names:
|
||||||
|
ll_find(ll, name)
|
||||||
|
time_fnd = time.perf_counter() - t1
|
||||||
|
s_fnd += time_fnd
|
||||||
|
results.append(["LinkedList", mode_name, "поиск", time_fnd])
|
||||||
|
|
||||||
|
|
||||||
|
t1 = time.perf_counter()
|
||||||
|
for name in d_names:
|
||||||
|
ll = ll_delete(ll, name)
|
||||||
|
time_del = time.perf_counter() - t1
|
||||||
|
s_del += time_del
|
||||||
|
results.append(["LinkedList", mode_name, "удаление", time_del])
|
||||||
|
|
||||||
|
print(f" Связный список ({mode_name}) | Среднее за 5 замеров ")
|
||||||
|
print(f"Вставка: {s_ins/5:.5f} сек.")
|
||||||
|
print(f"Поиск: {s_fnd/5:.5f} сек.")
|
||||||
|
print(f"Удаление: {s_del/5:.5f} сек.")
|
||||||
|
print("-" * 40)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ХЕШ-ТАБЛИЦА
|
||||||
|
for mode_name, data in [("случайный", records_shuffled), ("отсортированный", records_sorted)]:
|
||||||
|
s_ins = 0
|
||||||
|
s_fnd=0
|
||||||
|
s_del =0
|
||||||
|
for _ in range(5):
|
||||||
|
ht = [None] * 2000
|
||||||
|
|
||||||
|
|
||||||
|
t1 = time.perf_counter()
|
||||||
|
for name, phone in data:
|
||||||
|
ht = ht_insert(ht, name, phone)
|
||||||
|
time_ins = time.perf_counter() - t1
|
||||||
|
s_ins += time_ins
|
||||||
|
results.append(["HashTable", mode_name, "вставка", time_ins])
|
||||||
|
|
||||||
|
|
||||||
|
t1 = time.perf_counter()
|
||||||
|
for name in s_names:
|
||||||
|
ht_find(ht, name)
|
||||||
|
time_fnd = time.perf_counter() - t1
|
||||||
|
s_fnd += time_fnd
|
||||||
|
results.append(["HashTable", mode_name, "поиск", time_fnd])
|
||||||
|
|
||||||
|
|
||||||
|
t1 = time.perf_counter()
|
||||||
|
for name in d_names:
|
||||||
|
ht = ht_delete(ht, name)
|
||||||
|
time_del = time.perf_counter() - t1
|
||||||
|
s_del += time_del
|
||||||
|
results.append(["HashTable", mode_name, "удаление", time_del])
|
||||||
|
|
||||||
|
print(f" Хеш-таблица ({mode_name}) | Среднее за 5 замеров ")
|
||||||
|
print(f"Вставка: {s_ins/5:.5f} сек.")
|
||||||
|
print(f"Поиск: {s_fnd/5:.5f} сек.")
|
||||||
|
print(f"Удаление: {s_del/5:.5f} сек.")
|
||||||
|
print("-" * 40)
|
||||||
|
|
||||||
|
# ДЕРЕВО
|
||||||
|
|
||||||
|
for mode_name, data in [("случайный", records_shuffled), ("отсортированный", records_sorted)]:
|
||||||
|
s_ins = 0
|
||||||
|
s_fnd = 0
|
||||||
|
s_del = 0
|
||||||
|
for _ in range(5):
|
||||||
|
bst = None
|
||||||
|
|
||||||
|
|
||||||
|
t1 = time.perf_counter()
|
||||||
|
for name, phone in data:
|
||||||
|
bst = bst_insert(bst, name, phone)
|
||||||
|
time_ins = time.perf_counter() - t1
|
||||||
|
s_ins += time_ins
|
||||||
|
results.append(["BST", mode_name, "вставка", time_ins])
|
||||||
|
|
||||||
|
|
||||||
|
t1 = time.perf_counter()
|
||||||
|
for name in s_names:
|
||||||
|
bst_find(bst, name)
|
||||||
|
time_fnd = time.perf_counter() - t1
|
||||||
|
s_fnd += time_fnd
|
||||||
|
results.append(["BST", mode_name, "поиск", time_fnd])
|
||||||
|
|
||||||
|
|
||||||
|
t1 = time.perf_counter()
|
||||||
|
for name in d_names:
|
||||||
|
bst = bst_delete(bst, name)
|
||||||
|
time_del = time.perf_counter() - t1
|
||||||
|
s_del += time_del
|
||||||
|
results.append(["BST", mode_name, "удаление", time_del])
|
||||||
|
|
||||||
|
print(f"Двоичное дерево ({mode_name}) | Среднее за 5 замеров ")
|
||||||
|
print(f"Вставка: {s_ins/5:.5f} сек.")
|
||||||
|
print(f"Поиск: {s_fnd/5:.5f} сек.")
|
||||||
|
print(f"Удаление: {s_del/5:.5f} сек.")
|
||||||
|
print("-" * 40)
|
||||||
|
# Сохранение результатов
|
||||||
|
with open("docs/data/results.csv", "w", newline="", encoding="utf-8") as f:
|
||||||
|
writer = csv.writer(f)
|
||||||
|
writer.writerows(results)
|
||||||
61
VolkovVA/docs/data/grafic.py
Normal file
61
VolkovVA/docs/data/grafic.py
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
import csv
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
pth = r"C:\Users\vva26\2026-rff_mp\VolkovVA\docs\data\results.csv"
|
||||||
|
grf = r"C:\Users\vva26\2026-rff_mp\VolkovVA\docs\performance_chart.png"
|
||||||
|
|
||||||
|
dct = defaultdict(lambda: defaultdict(list))
|
||||||
|
|
||||||
|
with open(pth, "r", encoding="utf-8") as f:
|
||||||
|
rdr = csv.reader(f)
|
||||||
|
nxt = next(rdr)
|
||||||
|
|
||||||
|
for row in rdr:
|
||||||
|
if not row:
|
||||||
|
continue
|
||||||
|
str, mod, ope, tim = row
|
||||||
|
key = f"{str}\n({ope})"
|
||||||
|
dct[key][mod].append(float(tim))
|
||||||
|
|
||||||
|
lbl = []
|
||||||
|
rnd = []
|
||||||
|
srt = []
|
||||||
|
|
||||||
|
for key, mds in dct.items():
|
||||||
|
lbl.append(key)
|
||||||
|
avg_rnd = sum(mds["случайный"]) / len(mds["случайный"]) if mds["случайный"] else 0
|
||||||
|
avg_srt = sum(mds["отсортированный"]) / len(mds["отсортированный"]) if mds["отсортированный"] else 0
|
||||||
|
rnd.append(avg_rnd)
|
||||||
|
srt.append(avg_srt)
|
||||||
|
|
||||||
|
idx = range(len(lbl))
|
||||||
|
wth = 0.35
|
||||||
|
|
||||||
|
x_rnd = []
|
||||||
|
for i in idx:
|
||||||
|
x_rnd.append(i - wth/2)
|
||||||
|
|
||||||
|
x_srt = []
|
||||||
|
for i in idx:
|
||||||
|
x_srt.append(i + wth/2)
|
||||||
|
|
||||||
|
fig, axs = plt.subplots(figsize=(11, 6))
|
||||||
|
|
||||||
|
bar1 = axs.bar(x_rnd, rnd, wth, label='Случайные данные', color='#3498db')
|
||||||
|
bar2 = axs.bar(x_srt, srt, wth, label='Отсортированные данные', color='#e74c3c')
|
||||||
|
|
||||||
|
axs.set_title('Сравнение скорости операций в различных структурах данных', fontsize=13, fontweight='bold', pad=15)
|
||||||
|
axs.set_xticks(idx)
|
||||||
|
axs.set_xticklabels(lbl, rotation=15, ha='right', fontsize=10)
|
||||||
|
axs.legend(fontsize=10)
|
||||||
|
axs.grid(axis='y', linestyle='--', alpha=0.5)
|
||||||
|
|
||||||
|
axs.set_yscale('log')
|
||||||
|
axs.set_ylabel('Время выполнения в сек (Логарифмическая шкала)', fontsize=11)
|
||||||
|
|
||||||
|
plt.tight_layout()
|
||||||
|
|
||||||
|
plt.savefig(grf, dpi=300)
|
||||||
|
print(f"\n[OK] График сохранен в: {grf}")
|
||||||
|
plt.show()
|
||||||
91
VolkovVA/docs/data/results.csv
Normal file
91
VolkovVA/docs/data/results.csv
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
Структура,Режим,Операция,Время (сек)
|
||||||
|
LinkedList,случайный,вставка,4.958941400000185
|
||||||
|
LinkedList,случайный,поиск,0.008604499998909887
|
||||||
|
LinkedList,случайный,удаление,0.028961699999854318
|
||||||
|
LinkedList,случайный,вставка,4.586040099999082
|
||||||
|
LinkedList,случайный,поиск,0.008263100000476697
|
||||||
|
LinkedList,случайный,удаление,0.029679399998713052
|
||||||
|
LinkedList,случайный,вставка,4.6588382000009005
|
||||||
|
LinkedList,случайный,поиск,0.007250799999383162
|
||||||
|
LinkedList,случайный,удаление,0.030251800000769435
|
||||||
|
LinkedList,случайный,вставка,4.670033100001092
|
||||||
|
LinkedList,случайный,поиск,0.006605799999306328
|
||||||
|
LinkedList,случайный,удаление,0.027991499999188818
|
||||||
|
LinkedList,случайный,вставка,4.748308900001575
|
||||||
|
LinkedList,случайный,поиск,0.007203299999673618
|
||||||
|
LinkedList,случайный,удаление,0.03180229999998119
|
||||||
|
LinkedList,отсортированный,вставка,4.111856699999407
|
||||||
|
LinkedList,отсортированный,поиск,0.032833799999934854
|
||||||
|
LinkedList,отсортированный,удаление,0.0238707999997132
|
||||||
|
LinkedList,отсортированный,вставка,4.056196399998953
|
||||||
|
LinkedList,отсортированный,поиск,0.029753599999821745
|
||||||
|
LinkedList,отсортированный,удаление,0.02699679999932414
|
||||||
|
LinkedList,отсортированный,вставка,4.043270199999824
|
||||||
|
LinkedList,отсортированный,поиск,0.03809220000039204
|
||||||
|
LinkedList,отсортированный,удаление,0.031088699999600067
|
||||||
|
LinkedList,отсортированный,вставка,4.068934800001443
|
||||||
|
LinkedList,отсортированный,поиск,0.03372520000084478
|
||||||
|
LinkedList,отсортированный,удаление,0.022044399998776498
|
||||||
|
LinkedList,отсортированный,вставка,4.1079007999996975
|
||||||
|
LinkedList,отсортированный,поиск,0.03892860000087239
|
||||||
|
LinkedList,отсортированный,удаление,0.027481600000101025
|
||||||
|
HashTable,случайный,вставка,0.30640630000016245
|
||||||
|
HashTable,случайный,поиск,0.00013550000039685983
|
||||||
|
HashTable,случайный,удаление,0.0012347000010777265
|
||||||
|
HashTable,случайный,вставка,0.34630660000038915
|
||||||
|
HashTable,случайный,поиск,0.0001421999986632727
|
||||||
|
HashTable,случайный,удаление,0.0012489000000641681
|
||||||
|
HashTable,случайный,вставка,0.38971809999929974
|
||||||
|
HashTable,случайный,поиск,0.00016150000010384247
|
||||||
|
HashTable,случайный,удаление,0.002711900000576861
|
||||||
|
HashTable,случайный,вставка,0.324972099999286
|
||||||
|
HashTable,случайный,поиск,0.0001874999998108251
|
||||||
|
HashTable,случайный,удаление,0.0017291999993176432
|
||||||
|
HashTable,случайный,вставка,0.2981096000003163
|
||||||
|
HashTable,случайный,поиск,0.0001320000010309741
|
||||||
|
HashTable,случайный,удаление,0.0012389000003167894
|
||||||
|
HashTable,отсортированный,вставка,0.2988248999990901
|
||||||
|
HashTable,отсортированный,поиск,0.0030752000002394198
|
||||||
|
HashTable,отсортированный,удаление,0.0022033000004739733
|
||||||
|
HashTable,отсортированный,вставка,0.236953599998742
|
||||||
|
HashTable,отсортированный,поиск,0.001772999999957392
|
||||||
|
HashTable,отсортированный,удаление,0.001366500000585802
|
||||||
|
HashTable,отсортированный,вставка,0.2778657999988354
|
||||||
|
HashTable,отсортированный,поиск,0.002423300000373274
|
||||||
|
HashTable,отсортированный,удаление,0.0014498000000457978
|
||||||
|
HashTable,отсортированный,вставка,0.29585169999882055
|
||||||
|
HashTable,отсортированный,поиск,0.0017410000000381842
|
||||||
|
HashTable,отсортированный,удаление,0.0011991000010311836
|
||||||
|
HashTable,отсортированный,вставка,0.26809420000063255
|
||||||
|
HashTable,отсортированный,поиск,0.002089999999952852
|
||||||
|
HashTable,отсортированный,удаление,0.0012606000000232598
|
||||||
|
BST,случайный,вставка,0.02932920000057493
|
||||||
|
BST,случайный,поиск,0.00011919999997189734
|
||||||
|
BST,случайный,удаление,0.00013829999988956843
|
||||||
|
BST,случайный,вставка,0.03383949999988545
|
||||||
|
BST,случайный,поиск,0.00013100000069243833
|
||||||
|
BST,случайный,удаление,0.00015460000031453092
|
||||||
|
BST,случайный,вставка,0.03317650000099093
|
||||||
|
BST,случайный,поиск,0.00015159999929892365
|
||||||
|
BST,случайный,удаление,0.00017430000116291922
|
||||||
|
BST,случайный,вставка,0.034723400000075344
|
||||||
|
BST,случайный,поиск,0.00012229999992996454
|
||||||
|
BST,случайный,удаление,0.00013300000136950985
|
||||||
|
BST,случайный,вставка,0.1100944999998319
|
||||||
|
BST,случайный,поиск,0.00017110000044340268
|
||||||
|
BST,случайный,удаление,0.00023839999994379468
|
||||||
|
BST,отсортированный,вставка,6.630453600000692
|
||||||
|
BST,отсортированный,поиск,0.04603809999935038
|
||||||
|
BST,отсортированный,удаление,0.02620779999961087
|
||||||
|
BST,отсортированный,вставка,6.207381700000042
|
||||||
|
BST,отсортированный,поиск,0.05315580000024056
|
||||||
|
BST,отсортированный,удаление,0.034192999999504536
|
||||||
|
BST,отсортированный,вставка,6.164588699999513
|
||||||
|
BST,отсортированный,поиск,0.045654399998966255
|
||||||
|
BST,отсортированный,удаление,0.025836999999228283
|
||||||
|
BST,отсортированный,вставка,6.026949899998726
|
||||||
|
BST,отсортированный,поиск,0.05018319999908272
|
||||||
|
BST,отсортированный,удаление,0.03436810000130208
|
||||||
|
BST,отсортированный,вставка,5.9327873000002
|
||||||
|
BST,отсортированный,поиск,0.041103599998677964
|
||||||
|
BST,отсортированный,удаление,0.02514359999986482
|
||||||
|
Loading…
Reference in New Issue
Block a user