From cbcfc98cd559a24c99b371850107dfc4cb28efba Mon Sep 17 00:00:00 2001 From: Axy Date: Sun, 15 Mar 2026 23:15:32 +0100 Subject: [PATCH] More complete AVL, now with split and join --- __main__.py | 7 ++++++- amazeing/utils/avl.py | 41 +++++++++++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/__main__.py b/__main__.py index be26415..a6a59a2 100644 --- a/__main__.py +++ b/__main__.py @@ -32,10 +32,15 @@ keys2 = {i: tree2.append(i) for i in range(25)} for i in range(1, 10, 3): keys2[i].remove() -tree.join(tree2) +tree.rjoin(tree2) print(tree) +lhs_tree, rhs_tree = keys2[18].split_up() + +print(lhs_tree) +print(rhs_tree) + exit(0) diff --git a/amazeing/utils/avl.py b/amazeing/utils/avl.py index ce53209..26f2a1f 100644 --- a/amazeing/utils/avl.py +++ b/amazeing/utils/avl.py @@ -49,14 +49,21 @@ class Tree[T]: other.root = a self.root = b - def join(self, rhs: "Tree[T]") -> None: + def ljoin(self, lhs: "Tree[T]") -> None: + if self.height() >= lhs.height(): + self.__ljoin(lhs) + else: + lhs.__rjoin(self) + self.exchange(lhs) + + def rjoin(self, rhs: "Tree[T]") -> None: if self.height() >= rhs.height(): - self.rjoin(rhs) + self.__rjoin(rhs) else: - rhs.ljoin(self) + rhs.__ljoin(self) self.exchange(rhs) - def ljoin(self, lhs: "Tree[T]") -> None: + def __ljoin(self, lhs: "Tree[T]") -> None: if self.root is None: self.exchange(lhs) if self.root is None or lhs.root is None: @@ -72,7 +79,7 @@ class Tree[T]: new.update_height() new.parent.balance_one_propagate() - def rjoin(self, rhs: "Tree[T]") -> None: + def __rjoin(self, rhs: "Tree[T]") -> None: if self.root is None: self.exchange(rhs) if self.root is None or rhs.root is None: @@ -81,7 +88,7 @@ class Tree[T]: insert = rhs.root rhs.root = None while isinstance(curr, Branch) and curr.height > insert.height + 1: - curr = curr.lhs + curr = curr.rhs parent = curr.parent new = Branch(curr.parent, curr.with_parent, insert.with_parent) parent.replace(curr, new) @@ -103,6 +110,28 @@ class Node[T]: return self.parent return self.parent.root() + def split_up(self) -> tuple[Tree, Tree]: + """ + makes self.parent empty + """ + curr = self + lhs = Tree() + rhs = Tree() + while isinstance(curr.parent, Node): + curr_parent = curr.parent + extra = Tree() + if curr_parent.lhs is curr: + extra.root = curr_parent.rhs.with_parent(extra) + rhs.rjoin(extra) + elif curr_parent.rhs is curr: + extra.root = curr_parent.lhs.with_parent(extra) + lhs.ljoin(extra) + else: + raise Exception("Invalid AVL structure") + curr = curr_parent + curr.parent.root = None + return (lhs, rhs) + class Branch[T](Node[T]): def __init__( -- 2.53.0