Вычислительная практика I, ММФ, БГУ
Лаврова О.А., декабрь 2017
Большинство алгоритмов работы с деревьями основаны на обходах (tree traversing). Полный обход дерева -- это последовательная обработка всех узлов дерева по некоторому правилу. Результатом обхода дерева является линейное упорядочение узлов.
Основные обходы:
Названия обходов происходят от расположения корня по отношению к поддеревьям.
Если в представлении дерева фиксированы только ребра, ведущие от родительского узла (реализация представления в ЛР4), то существует ТОЛЬКО три обхода дерева: прямой, центрированный и обратный.
Обходы реализуются рекурсией. Итеративная реализация требует использования стека для "откладывания" на потом обработки некоторых узлов.
Центрированный обход реализует сортировку числовой последовательности для бинарного дерева поиска. Эффективность сортировки: $O(n)$ операций для обхода дерева + $O(n \log{(n)})$ для вставки $n$ элементов в бинарное дерево поиска, где $O(\log{(n)})$ операций необходимо для вставки элемента в сбалансированное дерево.
Напишите функцию LCR(tree), которая реализует центрированный обход для бинарного дерева поиска tree. Реализуйте обход с помощью рекурсии. Результатом функции должен быть список чисел, отсортированный по возрастанию.
Постройте в одной графической области исходный список чисел и список, полученный после центрированного обхода.
Сравните эффективность по времени сортировки последовательности из $10^3$ элементов с помощью встроенного метода sort для списков и с помощью центрированного обхода.
import matplotlib.pyplot as plt
%matplotlib inline
f = open("VP1LR4_data_rows.txt") # числа записаны в строки и разделены пробелами
source_data = [float(x) for row in f for x in row.split(' ')] # использование вложенных генераторов списка
# ВАЖНО: индексация для внешнего цикла расположена внутри
# (аналогично Table в Mathematica)
f.close()
source_data
tree = create_tree(source_data) # функция create_tree создана в ЛР4
print(tree)
Напишите функцию LCR самостоятельно
def LCR(tree):
""" центрированный обход бинарного дерева поиска: левое поддерево-корень-правое поддерево
Args:
tree: бинарное дерево поиска
Returns:
список, содержащий узлы дерева после обхода
"""
Your code should be here
sorted_data = LCR(tree)
sorted_data
plt.stem(source_data,'r-', label='Initial data')
plt.plot(sorted_data,'g.-',label='Sorted data')
plt.title('Sequences of numbers')
plt.legend()
import random as rnd
help(rnd.uniform)
rnd.uniform(0,100)
source_data = [rnd.uniform(0,100) for i in range(10**3)]
tree = create_tree(source_data)
sorted_data = LCR(tree)
plt.plot(source_data,'m.', label='Initial data')
plt.plot(sorted_data,'y.-',label='Sorted data')
plt.title('Sequences of numbers')
plt.legend()
Встроенный метод сортировки для списков
source_data_copy = source_data
source_data_copy.sort()
plt.plot(source_data_copy,'m.')
Оцените время, необходимое на сортировку с помощью функции LCR и метода sort. Используйте подход из ЛР2.
Напишите функции min(tree) и max(tree), для нахождения минимального и максимального значений бинарного дерева поиска tree. Реализуйте функции с помощью рекурсии.