Исходный код EJIO.utils.component.tree.bst

## /utils/component/tree/bst.py

from collections.abc import Iterator, Iterable
from threading import RLock
from typing import Any
from ...struct import TreeNode, Stack

__all__ = [
    'BSTNode',
]


[документация] class BSTNode(TreeNode): """ Узел двоичного (бинарного) дерева поиска (Binary Search Tree). Содержит строго левого (меньшего) и правого (большего) потомков. """ __slots__ = ('_value', 'left', 'right', '_lock') def __init__(self, *args: Any) -> None: """ Инициализирует узел бинарного дерева поиска. Примеры: BSTNode(50) # Одиночный корень BSTNode([50, 30, 70, 20, 40]) # Автоматическое построение дерева из списка/итератора """ self._value: Any = None self.left: 'BSTNode | None' = None self.right: 'BSTNode | None' = None self._lock: RLock = RLock() if args: if len(args) == 1 and isinstance(args[0], Iterable) and not isinstance(args[0], str): iterator: Iterator[Any] = iter(args[0]) try: self._value = next(iterator) for item in iterator: self.insert(item) except StopIteration: pass else: if len(args) == 1: self._value = args[0] else: self._value = args[0] for item in args[1:]: self.insert(item) @property def value(self) -> Any: """ Возвращает значение текущего узла. :return: Значение текущего узла. """ with self._lock: return self._value @property def children(self) -> Iterable[TreeNode]: """ Потокобезопасная проекция двоичной структуры на общий контракт TreeNode. Возвращает левого и правого детей, если они существуют. :return: Список потомков. """ with self._lock: res = [] if self.left is not None: res.append(self.left) if self.right is not None: res.append(self.right) return res
[документация] def insert(self, val: Any) -> None: """ Потокобезопасная упорядоченная вставка элемента со сравнением значений. :param val: Значение нового узла. """ with self._lock: if val < self._value: if self.left is None: self.left = BSTNode(val) else: self.left.insert(val) else: if self.right is None: self.right = BSTNode(val) else: self.right.insert(val)
[документация] def destroy(self) -> None: """ Итеративное, потокобезопасное и каскадное уничтожение бинарного дерева поиска. Полностью защищено от RecursionError и оптимизировано по скорости. """ with self._lock: if self._value is None: return # Дерево уже уничтожено # Создаем итеративный стек для обхода всех узлов nodes_stack: Stack[BSTNode] = Stack() nodes_stack.push(self) # Массив для плоского сбора всех узлов, подлежащих очистке nodes_to_clear: list[BSTNode] = [] # Шаг 1: Итеративно собираем все узлы в плоский список (без рекурсии) while not nodes_stack.empty: current_node = nodes_stack.pop() if current_node is None: continue nodes_to_clear.append(current_node) # Заталкиваем детей в стек if current_node.left is not None: nodes_stack.push(current_node.left) if current_node.right is not None: nodes_stack.push(current_node.right) # Шаг 2: Обходим собранные узлы с конца и жестко зануляем их внутренности # Это гарантирует, что мы сначала отвяжем листья, а затем родительские ветви for node in reversed(nodes_to_clear): # Захватываем локальный замок каждого конкретного узла перед очисткой with node._lock: node.left = None node.right = None node._value = None # Высвобождаем ссылку на сам замок узла node._lock = None # type: ignore[assignment] # Зануляем локальный замок корневого узла self._lock = None # type: ignore[assignment]
def __repr__(self) -> str: """ Строковое представление узла. :return: Представление узла в виде строки. """ with self._lock: return f"BSTNode({self._value!r})"