Декартовы деревья. Операции над Декартовыми деревьями.
Определение
Декартово дерево (также известное как treap) — это структура данных, которая объединяет свойства бинарного дерева поиска
(BST) и кучи
(heap). В Декартовом дереве каждому узлу присваивается два значения: ключ и приоритет.
- Узлы организованы по ключам как в BST (для любого узла, ключи в левом поддереве меньше, а в правом — больше).
- Узлы организованы по приоритетам как в куче (приоритеты потомков всегда меньше приоритета родительского узла).
Операции
- Вставка нового элемента начинается как в обычном BST, а затем восстанавливается свойство кучи с помощью вращений (ротаций).
- Удаление
- Элемент сначала переводиться в лист с помощью ротаций, сохраняя свойство кучи.
- Лист удаляется стандартным способом.
- Разделение
- Разделяет дерево на два поддерева, используя ключ разделения.
- Операция проводится рекурсивно и сохраняет свойства BST и кучи.
- Слияние
- Сливает два дерева, сохраняя свойства BST и кучи.
- Выбирает корень с большим приоритетом и рекурсивно сливает поддеревья.
python
class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
class CartesianTree:
def __init__(self):
self.root = None
def insert(self, key):
self.root = self._insert(self.root, key)
def remove(self, key):
self.root = self._remove(self.root, key)
def split(self, key):
left_tree, right_tree = self._split(self.root, key)
return left_tree, right_tree
def merge(self, other):
self.root = self._merge(self.root, other.root)
def _insert(self, node, key):
if node is None:
return Node(key)
if key < node.key:
node.left = self._insert(node.left, key)
if node.left and node.left.key > node.key:
node = self._rotate_right(node)
elif key > node.key:
node.right = self._insert(node.right, key)
if node.right and node.right.key < node.key:
node = self._rotate_left(node)
return node
def _rotate_right(self, node):
new_root = node.left
node.left = new_root.right
new_root.right = node
return new_root
def _rotate_left(self, node):
new_root = node.right
node.right = new_root.left
new_root.left = node
return new_root
def _remove(self, node, key):
if node is None:
return node
if key < node.key:
node.left = self._remove(node.left, key)
elif key > node.key:
node.right = self._remove(node.right, key)
else:
if node.left is None:
return node.right
if node.right is None:
return node.left
temp = self._find_min(node.right)
node.key = temp.key
node.right = self._remove(node.right, temp.key)
return node
def _find_min(self, node):
current = node
while current.left is not None:
current = current.left
return current
def _split(self, node, key):
if node is None:
return None, None
if key < node.key:
left_subtree, right_subtree = self._split(node.left, key)
node.left = right_subtree
return left_subtree, node
else:
left_subtree, right_subtree = self._split(node.right, key)
node.right = left_subtree
return node, right_subtree
def _merge(self, left, right):
if left is None:
return right
if right is None:
return left
if left.key < right.key:
left.right = self._merge(left.right, right)
return left
else:
right.left = self._merge(left, right.left)
return right