Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лаба по деревьям - 3 сем АИСД.docx
Скачиваний:
0
Добавлен:
08.07.2025
Размер:
1.56 Mб
Скачать

Графики для кч-дерева

from RBT import RBT_func

import matplotlib.pyplot as plt

import numpy as np

l = 1000

k = []

for i in range(1,l+1):

k.append(i)

m = []

for o in range(1,l+1):

m.append(k[:o])

he = []

ma = []

for j in range(len(m)):

rbt = RBT_func()

root = None

for key in m[j]:

root = rbt.insert(key)

ma.append(len(m[j]))

#print(rbt.level_order_traversal(rbt.root))

hei=rbt.height_of_tree(rbt.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

n = np.linspace(1, 1000, 400) # от 1 до 100, 400 точек

y = 2*np.log2(n+1.0)

plt.plot(n, y, label='2*log(n+1)', color='black', )

plt.plot(ma, he, color = 'orange')

plt.title('Зависимость высоты RBT-дерева от количества ключей')

plt.xlabel('Количество ключей')

plt.ylabel('Высота дерева h')

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 = 'orange')

plt.plot(x, regression_line, label="Регрессия log(x)", color="red")

plt.title("Зависимость высоты RBT-дерева от количества ключей")

plt.xlabel('Количество ключей')

plt.ylabel('Высота дерева')

plt.grid()

plt.show()

КЧ-дерево

class Node:

def __init__(self, key, color="red", left=None, right=None, parent=None):

self.key = key

self.color = color # "red" or "black"

self.left = left

self.right = right

self.parent = parent

self.height = 0

class RBT_func:

def __init__(self):

self.TNULL = Node(key=None, color="black") # Sentinel node

self.root = self.TNULL

def search(self, key):

current = self.root

while current != self.TNULL and key != current.key:

if key < current.key:

current = current.left

else:

current = current.right

return current

def left_rotate(self, x):

y = x.right

x.right = y.left

if y.left != self.TNULL:

y.left.parent = x

y.parent = x.parent

if x.parent is None:

self.root = y

elif x == x.parent.left:

x.parent.left = y

else:

x.parent.right = y

y.left = x

x.parent = y

def right_rotate(self, x):

y = x.left

x.left = y.right

if y.right != self.TNULL:

y.right.parent = x

y.parent = x.parent

if x.parent is None:

self.root = y

elif x == x.parent.right:

x.parent.right = y

else:

x.parent.left = y

y.right = x

x.parent = y

def insert(self, key):

node = Node(key=key, color="red", left=self.TNULL, right=self.TNULL)

parent = None

current = self.root

while current != self.TNULL:

parent = current

if node.key < current.key:

current = current.left

else:

current = current.right

node.parent = parent

if parent is None:

self.root = node

elif node.key < parent.key:

parent.left = node

else:

parent.right = node

self.insert_fixup(node)

def insert_fixup(self, node):

while node.parent and node.parent.color == "red":

if node.parent == node.parent.parent.left:

uncle = node.parent.parent.right

if uncle.color == "red":

node.parent.color = "black"

uncle.color = "black"

node.parent.parent.color = "red"

node = node.parent.parent

else:

if node == node.parent.right:

node = node.parent

self.left_rotate(node)

node.parent.color = "black"

node.parent.parent.color = "red"

self.right_rotate(node.parent.parent)

else:

uncle = node.parent.parent.left

if uncle.color == "red":

node.parent.color = "black"

uncle.color = "black"

node.parent.parent.color = "red"

node = node.parent.parent

else:

if node == node.parent.left:

node = node.parent

self.right_rotate(node)

node.parent.color = "black"

node.parent.parent.color = "red"

self.left_rotate(node.parent.parent)

self.root.color = "black"

def transplant(self, u, v):

if u.parent is None:

self.root = v

elif u == u.parent.left:

u.parent.left = v

else:

u.parent.right = v

v.parent = u.parent

def delete(self, key):

node = self.search(key)

if node == self.TNULL:

return # Node not found

y = node

y_original_color = y.color

if node.left == self.TNULL:

x = node.right

self.transplant(node, node.right)

elif node.right == self.TNULL:

x = node.left

self.transplant(node, node.left)

else:

y = self.minimum(node.right)

y_original_color = y.color

x = y.right

if y.parent == node:

x.parent = y

else:

self.transplant(y, y.right)

y.right = node.right

y.right.parent = y

self.transplant(node, y)

y.left = node.left

y.left.parent = y

y.color = node.color

if y_original_color == "black":

self.delete_fixup(x)

def delete_fixup(self, x):

while x != self.root and x.color == "black":

if x == x.parent.left:

sibling = x.parent.right

if sibling.color == "red":

sibling.color = "black"

x.parent.color = "red"

self.left_rotate(x.parent)

sibling = x.parent.right

if sibling.left.color == "black" and sibling.right.color == "black":

sibling.color = "red"

x = x.parent

else:

if sibling.right.color == "black":

sibling.left.color = "black"

sibling.color = "red"

self.right_rotate(sibling)

sibling = x.parent.right

sibling.color = x.parent.color

x.parent.color = "black"

sibling.right.color = "black"

self.left_rotate(x.parent)

x = self.root

else:

sibling = x.parent.left

if sibling.color == "red":

sibling.color = "black"

x.parent.color = "red"

self.right_rotate(x.parent)

sibling = x.parent.left

if sibling.left.color == "black" and sibling.right.color == "black":

sibling.color = "red"

x = x.parent

else:

if sibling.left.color == "black":

sibling.right.color = "black"

sibling.color = "red"

self.left_rotate(sibling)

sibling = x.parent.left

sibling.color = x.parent.color

x.parent.color = "black"

sibling.left.color = "black"

self.right_rotate(x.parent)

x = self.root

x.color = "black"

def minimum(self, node):

while node.left != self.TNULL:

node = node.left

return node

def preorder(self, root):

if root is not None:

if root.key == None:

print('', end='')

else:

print(root.key, end=' ')

self.preorder(root.left)

self.preorder(root.right)

def inorder(self, root):

if root is not None:

self.inorder(root.left)

if root.key == None:

print('', end='')

else:

print(root.key, end=' ')

self.inorder(root.right)

def postorder(self, root):

if root is not None:

self.postorder(root.left)

self.postorder(root.right)

if root.key==None:print('',end='')

else: print(root.key, end=' ')

def level_order_traversal(self, root):

if root is None:

return []

result = []

queue = [root] # Используем список в качестве очереди

while queue:

current = queue.pop(0) # Удаляем первый элемент из списка

result.append(current.key)

# Добавляем дочерние элементы в конец списка

if current.left:

queue.append(current.left)

if current.right:

queue.append(current.right)

result1 = []

for i in result:

if i!=None: result1.append(i)

return result1

def height_of_tree(self, node):

if node is None:

return -2 # Возвращаем -1 для учета высоты при наличии узла

else:

left_height = self.height_of_tree(node.left)

right_height = self.height_of_tree(node.right)

#print('промежуточно:')

#print(left_height,right_height)

return max(left_height, right_height) + 1