
- •Теоретическая часть
- •Основные операции с авл-деревом
- •Вставка:
- •Удаление
- •Балансировка после вставки/удаления:
- •Верхняя оценка высоты авл-дерева
- •Красно-черное дерево (rb Tree)
- •Основные операции с красно-черным деревом
- •Балансировка дерева после вставки:
- •Балансировка дерева после удаления:
- •Верхняя оценка высоты красно-черного дерева
- •Практическая часть Асимптотика Бинарное дерево поиска (bst)
- •Лучший случай:
- •Средний случай:
- •Худший случай:
- •Зависимость высоты дерева от количества ключей Бинарное дерево поиска
- •Красно-черное дерево
- •Обходы дерева
- •Обход дерева в ширину
- •Обход дерева в глубину Прямой обход или preorder
- •Симметричый (центрированный) обход или inorder
- •Обратный обход или postorder
- •Код программы Графики для Бинарного дерева поиска:
- •Бинарное дерево поиска:
- •Графики для авл-дерева
- •Графики для кч-дерева
- •Обход деревьев
Код программы Графики для Бинарного дерева поиска:
from BSTree import BST_func
import matplotlib.pyplot as plt
import random
import numpy as np
l = 1000
k = []
for i in range(l):
p = random.randint(1,1000)
k.append(p)
m = []
for o in range(1,l+1):
m.append(k[:o])
he = []
ma = []
for j in range(len(m)):
bst = BST_func()
root = None
for key in m[j]:
root = bst.insert(root, key)
ma.append(len(m[j]))
#print("Симметричный обход:")
#bst.inorder(root)
hei=bst.height_of_tree(root)
#print("Высота дерева:", hei)
he.append(hei)
print(ma[0],he[0])
for i in range(1,len(ma)):
if he[i-1] != he[i]:
print(ma[i],he[i])
x1 = ma
y1 = he
plt.plot(x1, y1, color = 'green')
plt.title('Зависимость высоты BST-дерева от количества ключей')
plt.xlabel('Количество ключей')
plt.ylabel('Высота дерева')
plt.grid()
plt.show()
x = np.array(x1)
y = np.array(y1)
log_x = np.log2(x)
coefficients = np.polyfit(log_x, y, 1)
print('коэффы:', coefficients)
regression_line = np.polyval(coefficients, log_x)
#plt.scatter(x, y, label="Данные", color="blue")
plt.plot(x1, y1, color = 'green')
plt.plot(x, regression_line, label="Регрессия log(n)", color="red")
plt.title("Зависимость высоты BST-дерева от количества ключей")
plt.xlabel('Количество ключей')
plt.ylabel('Высота дерева')
plt.grid()
plt.show()
Бинарное дерево поиска:
class TreeNode:
def __init__(self, key):
self.left = None
self.right = None
self.val = key
class BST_func:
# def __init__(self):
# self.root = None
def search(self, root, key):
if root is None or root.val == key:
return root
if key < root.val:
return self.search(root.left, key)
else:
return self.search(root.right, key)
def insert(self, root, key):
if root is None:
return TreeNode(key)
else:
if key < root.val:
root.left = self.insert(root.left, key)
else:
root.right = self.insert(root.right, key)
return root
def delete_node(self, root, key):
# Базовый случай: если дерево пустое
if root is None:
return root
# Рекурсивно ищем узел для удаления
if key < root.val:
root.left = self.delete_node(root.left, key)
elif key > root.val:
root.right = self.delete_node(root.right, key)
else:
# Узел с единственным дочерним узлом или без дочерних узлов
if root.left is None:
return root.right
elif root.right is None:
return root.left
# Узел с двумя дочерними узлами: получаем наименьшее значение из правого поддерева (или наибольшее из левого)
min_larger_node = self.get_min_value_node(root.right)
root.val = min_larger_node.val
root.right = self.delete_node(root.right, min_larger_node.val)
return root
def get_min_value_node(self, node):
current = node
while current.left is not None:
current = current.left
return current
def preorder(self, root):
if root is not None:
print(root.val, end=' ')
self.preorder(root.left)
self.preorder(root.right)
def inorder(self, root):
if root is not None:
self.inorder(root.left)
print(root.val, end=' ')
self.inorder(root.right)
def postorder(self, root):
if root is not None:
self.postorder(root.left)
self.postorder(root.right)
print(root.val, end=' ')
def height_of_tree(self, node):
if node is None:
return -1 # Возвращаем -1 для учета высоты при наличии узла
else:
left_height = self.height_of_tree(node.left)
right_height = self.height_of_tree(node.right)
return max(left_height, right_height) + 1
def level_order_traversal(self, root):
if root is None:
return []
result = []
queue = [root] # Используем список в качестве очереди
while queue:
current = queue.pop(0) # Удаляем первый элемент из списка
result.append(current.val)
# Добавляем дочерние элементы в конец списка
if current.left:
queue.append(current.left)
if current.right:
queue.append(current.right)
return result