Cleaning up 'add' algorithm, naming and publishing

This commit is contained in:
Andrew Golovashevich 2025-12-29 21:25:29 +03:00
parent ba1a8d0533
commit e6fb9bf061
4 changed files with 49 additions and 189 deletions

View File

@ -1,79 +0,0 @@
fun balanceAfterLinking(node: NODE) {
this._setColor(node, Color.RED)
var current: NODE = node
while (true) {
val parent = this._getParent(current)
if (parent == null) {
current.__assertIsRoot()
this._setColor(current, Color.BLACK)
break
}
if (this._getColor(parent) == Color.BLACK) {
break
}
val grandParent = this._getParent(parent)
if (grandParent == null) {
parent.__assertIsRoot()
this._setColor(parent, Color.BLACK)
break
}
when {
this._checkSame(parent, this._getLeftChild(grandParent)) -> {
val uncle = this._getRightChild(grandParent)
if (uncle != null && this._getColor(uncle) == Color.RED) {
this._setColor(parent, Color.BLACK)
this._setColor(uncle, Color.BLACK)
this._setColor(grandParent, Color.RED)
current = grandParent
continue
}
when {
this._checkSame(current, this._getLeftChild(parent)) -> {
this.__rotateRight_Switch(grandParent)
continue
}
this._checkSame(current, this._getRightChild(parent)) -> {
this.__rotateLeft_Left(parent, grandParent)
current = parent
continue
}
else -> this.__throwTreeCorruptedNotChild(current, parent)
}
}
this._checkSame(parent, this._getRightChild(grandParent)) -> {
val uncle = this._getLeftChild(grandParent)
if (uncle != null && this._getColor(uncle) == Color.RED) {
this._setColor(parent, Color.BLACK)
this._setColor(uncle, Color.BLACK)
this._setColor(grandParent, Color.RED)
current = grandParent
continue
}
when {
this._checkSame(current, this._getRightChild(parent)) -> {
this.__rotateLeft_Switch(grandParent)
continue
}
this._checkSame(current, this._getLeftChild(parent)) -> {
this.__rotateRight_Right(parent, grandParent)
current = parent
continue
}
else -> this.__throwTreeCorruptedNotChild(current, parent)
}
}
else -> this.__throwTreeCorruptedNotChild(parent, grandParent)
}
}
}

View File

@ -1,5 +1,4 @@
use crate::context::{Color, RedBlackTreeColorContext}; use crate::context::{Color, RedBlackTreeColorContext};
use binary_tree_core_0::NodeRefContainer;
use binary_tree_core_0::base_context::{ use binary_tree_core_0::base_context::{
BinaryTreeChildrenGetterContext, BinaryTreeDirection, BinaryTreeDirectionDispatcherClojure, BinaryTreeChildrenGetterContext, BinaryTreeDirection, BinaryTreeDirectionDispatcherClojure,
BinaryTreeRootGetter, BinaryTreeRootGetter,
@ -10,109 +9,27 @@ use binary_tree_core_0::directed_context::{
use binary_tree_core_0::relation_context::{ use binary_tree_core_0::relation_context::{
BinaryTreeRelationSetterContext, BinaryTreeRootRelationSetterContext, BinaryTreeRelationSetterContext, BinaryTreeRootRelationSetterContext,
}; };
use std::mem::MaybeUninit;
use std::ptr::NonNull;
pub trait AddRecContext: pub trait RedBlackTreeAddingContext:
BinaryTreeRootGetter BinaryTreeRootGetter
+ BinaryTreeChildrenGetterContext
+ BinaryTreeRootRelationSetterContext + BinaryTreeRootRelationSetterContext
+ BinaryTreeRelationSetterContext + BinaryTreeRelationSetterContext
+ BinaryTreeDirectionDispatcherClojure
+ RedBlackTreeColorContext + RedBlackTreeColorContext
{ {
fn getLinkingContext(
&mut self,
) -> impl RedBlackTreeAddingContext_Linking<NodeRef = Self::NodeRef>;
fn getBalancingContext(
&mut self,
) -> impl RedBlackTreeAddingContext_Balancing<NodeRef = Self::NodeRef>;
} }
struct Frame<NodeRef> { pub struct ParentInfo<NodeRef: binary_tree_core_0::NodeRef> {
node: NodeRef, node: NodeRef,
dir: BinaryTreeDirection, dir: BinaryTreeDirection,
} }
struct Stack<T> { pub fn add<Ctx: RedBlackTreeAddingContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
start: NonNull<T>,
ptr: NonNull<T>,
}
impl<T> Stack<T> {
fn init<const SIZE: usize>(buffer: &mut [MaybeUninit<T>; SIZE]) -> Self {
unsafe {
let start = NonNull::new_unchecked(
((*buffer.as_mut_ptr()).as_mut_ptr())
.offset(const { 0isize.strict_add_unsigned(SIZE) }),
);
return Self { start, ptr: start };
}
}
fn push(&mut self, value: T) {
unsafe {
let newPtr = self.ptr.offset(-1);
newPtr.as_ptr().write(value);
self.ptr = newPtr;
}
}
fn _get<const OFFSET: usize>(&self) -> &T {
unsafe {
let loc = self
.ptr
.offset(const { 0isize.strict_add_unsigned(OFFSET) });
return loc.as_ref();
}
}
fn getParent(&self) -> &T {
return self._get::<0>();
}
fn getGrandParent(&self) -> &T {
return self._get::<1>();
}
fn getGrandGrandParent(&self) -> Option<&T> {
match self.hasGrandGrandParent() {
false => None,
true => Some(self._get::<2>()),
}
}
fn pop(&mut self) -> T {
unsafe {
let newPtr = self.ptr.offset(1);
let value = self.ptr.read();
self.ptr = newPtr;
return value;
}
}
fn popDiscard(&mut self) {
unsafe {
self.ptr = self.ptr.offset(1);
}
}
fn replaceTop(&mut self, value: T) {
unsafe {
self.ptr.write(value);
}
}
fn _has<const OFFSET: usize>(&self) -> bool {
unsafe {
return self
.ptr
.offset(const { 0isize.strict_add_unsigned(OFFSET) })
< self.start;
}
}
fn hasGrandParent(&self) -> bool {
return self._has::<1>();
}
fn hasGrandGrandParent(&self) -> bool {
return self._has::<2>();
}
}
pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
ctx.clearLeftChild(newNode.clone()); ctx.clearLeftChild(newNode.clone());
ctx.clearRightChild(newNode.clone()); ctx.clearRightChild(newNode.clone());
ctx.setColor(newNode.clone(), Color::RED); ctx.setColor(newNode.clone(), Color::RED);
@ -125,13 +42,13 @@ pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
return; return;
} }
Some(root) => { Some(root) => {
link(ctx, root, newNode); _link(&mut ctx.getLinkingContext(), root, newNode);
balance(ctx); _balance(&mut ctx.getBalancingContext());
} }
} }
} }
trait LinkingContext: pub trait RedBlackTreeAddingContext_Linking:
BinaryTreeChildrenGetterContext BinaryTreeChildrenGetterContext
+ BinaryTreeRelationSetterContext + BinaryTreeRelationSetterContext
+ BinaryTreeDirectionDispatcherClojure + BinaryTreeDirectionDispatcherClojure
@ -139,7 +56,11 @@ trait LinkingContext:
fn stackAddParentInfo(&mut self, node: Self::NodeRef, dir: BinaryTreeDirection); fn stackAddParentInfo(&mut self, node: Self::NodeRef, dir: BinaryTreeDirection);
} }
fn link<Ctx: LinkingContext>(ctx: &mut Ctx, mut it: Ctx::NodeRef, newNode: Ctx::NodeRef) { fn _link<Ctx: RedBlackTreeAddingContext_Linking>(
ctx: &mut Ctx,
mut it: Ctx::NodeRef,
newNode: Ctx::NodeRef,
) {
loop { loop {
let dir = ctx let dir = ctx
.determineDirection(it.clone()) .determineDirection(it.clone())
@ -166,22 +87,25 @@ fn link<Ctx: LinkingContext>(ctx: &mut Ctx, mut it: Ctx::NodeRef, newNode: Ctx::
} }
} }
trait BalancingContext: RedBlackTreeColorContext { pub trait RedBlackTreeAddingContext_Balancing: RedBlackTreeColorContext {
fn getLeftDirectedContext(&mut self) -> impl DirectedBalancingContext<NodeRef = Self::NodeRef>; fn getLeftDirectedContext(
fn getRightDirectedContext(&mut self) &mut self,
-> impl DirectedBalancingContext<NodeRef = Self::NodeRef>; ) -> impl RedBlackTreeAddingContext_DirectedBalancing<NodeRef = Self::NodeRef>;
fn getRightDirectedContext(
&mut self,
) -> impl RedBlackTreeAddingContext_DirectedBalancing<NodeRef = Self::NodeRef>;
fn stackPopParentInfo(&self) -> Option<Frame<Self::NodeRef>>; fn stackPopParentInfo(&self) -> Option<ParentInfo<Self::NodeRef>>;
} }
trait DirectedBalancingContext: pub trait RedBlackTreeAddingContext_DirectedBalancing:
RedBlackTreeColorContext + DirectedBinaryTreeChildrenGetterContext RedBlackTreeColorContext + DirectedBinaryTreeChildrenGetterContext
{ {
fn rotateForward_Forward(&mut self, parent: Self::NodeRef, pivot: Self::NodeRef); fn rotateForward_Forward(&mut self, parent: Self::NodeRef, pivot: Self::NodeRef);
fn rotateOpposite_GrandParent(&mut self, pivot: Self::NodeRef); fn rotateOpposite_GrandParent(&mut self, pivot: Self::NodeRef);
} }
fn balance<Ctx: BalancingContext>(ctx: &mut Ctx) { fn _balance<Ctx: RedBlackTreeAddingContext_Balancing>(ctx: &mut Ctx) {
loop { loop {
let parent; let parent;
match ctx.stackPopParentInfo() { match ctx.stackPopParentInfo() {
@ -215,10 +139,10 @@ fn balance<Ctx: BalancingContext>(ctx: &mut Ctx) {
} }
} }
fn _directed<Ctx: DirectedBalancingContext>( fn _directed<Ctx: RedBlackTreeAddingContext_DirectedBalancing>(
ctx: &mut Ctx, ctx: &mut Ctx,
grandparent: Frame<Ctx::NodeRef>, grandparent: ParentInfo<Ctx::NodeRef>,
parent: Frame<Ctx::NodeRef>, parent: ParentInfo<Ctx::NodeRef>,
) -> bool { ) -> bool {
let uncle = ctx.getOppositeChild(grandparent.node.clone()); let uncle = ctx.getOppositeChild(grandparent.node.clone());
if let Some(uncle) = uncle { if let Some(uncle) = uncle {
@ -233,7 +157,7 @@ fn balance<Ctx: BalancingContext>(ctx: &mut Ctx) {
let normalizedParent; let normalizedParent;
if grandparent.dir != parent.dir { if grandparent.dir != parent.dir {
normalizedParent = Frame { normalizedParent = ParentInfo {
node: ctx.getOppositeChild(parent.node.clone()).unwrap(), node: ctx.getOppositeChild(parent.node.clone()).unwrap(),
dir: grandparent.dir, dir: grandparent.dir,
}; };
@ -250,3 +174,18 @@ fn balance<Ctx: BalancingContext>(ctx: &mut Ctx) {
} }
} }
} }
pub fn balanceAfterLinking<
Ctx: RedBlackTreeAddingContext_Balancing + BinaryTreeRelationSetterContext + BinaryTreeRootGetter,
>(
ctx: &mut Ctx,
newNode: Ctx::NodeRef,
) {
ctx.clearLeftChild(newNode.clone());
ctx.clearRightChild(newNode.clone());
ctx.setColor(newNode.clone(), Color::RED);
_balance(ctx);
ctx.setColor(ctx.getRoot().unwrap(), Color::BLACK)
}

View File

@ -1 +1 @@
mod add; pub mod add;

View File

@ -1,4 +1,4 @@
mod algo; pub mod algo;
mod context; pub mod context;