-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlab_6
More file actions
129 lines (105 loc) · 4.96 KB
/
lab_6
File metadata and controls
129 lines (105 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import timeit
import matplotlib.pyplot as plt
from typing import Callable, List
#Рекурсивная версия дерева
def build_tree_recursive(
height: int,
root: int,
left_branch: Callable[[int], int] = lambda x: x * 2 + 1,
right_branch: Callable[[int], int] = lambda x: 2 * x - 1
) -> List:
"""
Рекурсивное построение бинарного дерева.
Каждый узел представлен в виде списка:
[значение, левый_потомок, правый_потомок].
Пустые ветви обозначаются пустым списком [].
:param height: высота дерева (количество уровней)
:param root: значение корня дерева
:param left_branch: функция для вычисления левого потомка
:param right_branch: функция для вычисления правого потомка
"""
if height <= 0:
return []
return [
root,
build_tree_recursive(height - 1, left_branch(root), left_branch, right_branch),
build_tree_recursive(height - 1, right_branch(root), left_branch, right_branch)
]
#Итеративная версия дерева
def build_tree_iterative(
height: int,
root: int,
left_branch: Callable[[int], int] = lambda x: x * 2 + 1,
right_branch: Callable[[int], int] = lambda x: 2 * x - 1
) -> List:
"""
Итеративное построение бинарного дерева через цикл.
Каждый узел представлен в виде списка:
[значение, левый_потомок, правый_потомок].
Пустые ветви обозначаются пустым списком [].
:param height: высота дерева
:param root: значение корня дерева
:param left_branch: функция для вычисления левого потомка
:param right_branch: функция для вычисления правого потомка
"""
if height < 1:
return []
tree = [root, [], []]
current_level = [tree]
level = 1
while level < height:
next_level = []
for node in current_level:
left_value = left_branch(node[0])
right_value = right_branch(node[0])
left_node = [left_value, [], []]
right_node = [right_value, [], []]
node[1] = left_node
node[2] = right_node
next_level.append(left_node)
next_level.append(right_node)
current_level = next_level
level += 1
return tree
#Функция для бенчмарка
def benchmark(func: Callable, heights: List[int], root: int = 9, number: int = 10, repeat: int = 3) -> List[float]:
"""
Замеряет время выполнения функции построения дерева для разных высот.
:param func: функция построения дерева (рекурсивная или итеративная)
:param heights: список высот деревьев для тестирования
:param root: значение корня дерева
:param number: количество повторов одной функции в одном замере
:param repeat: количество повторов для усреднения времени
"""
results = []
for h in heights:
times = timeit.repeat(lambda: func(h, root), number=number, repeat=repeat)
results.append(min(times))
return results
def main():
"""
Основная функция:
- задаёт параметры дерева (root=9, высоты 1..6)
- измеряет время построения рекурсивного и итеративного дерева
- выводит результаты в консоль
- строит график времени построения
"""
ROOT = 9
HEIGHTS = list(range(1, 7)) # высоты деревьев от 1 до 6
# Засекаем время
recursive_times = benchmark(build_tree_recursive, HEIGHTS, root=ROOT)
iterative_times = benchmark(build_tree_iterative, HEIGHTS, root=ROOT)
# Выводим результаты
for h, r, i in zip(HEIGHTS, recursive_times, iterative_times):
print(f"Высота {h}: рекурсивно = {r:.6f}s, итеративно = {i:.6f}s")
# Строим график
plt.plot(HEIGHTS, recursive_times, label="Рекурсивная")
plt.plot(HEIGHTS, iterative_times, label="Итеративная")
plt.xlabel("Высота дерева")
plt.ylabel("Время построения (сек)")
plt.title("Сравнение рекурсивного и итеративного построения дерева")
plt.legend()
plt.grid(True)
plt.show()
if __name__ == "__main__":
main()