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 binary_tree_core_0::NodeRefContainer;
use binary_tree_core_0::base_context::{
BinaryTreeChildrenGetterContext, BinaryTreeDirection, BinaryTreeDirectionDispatcherClojure,
BinaryTreeRootGetter,
@ -10,109 +9,27 @@ use binary_tree_core_0::directed_context::{
use binary_tree_core_0::relation_context::{
BinaryTreeRelationSetterContext, BinaryTreeRootRelationSetterContext,
};
use std::mem::MaybeUninit;
use std::ptr::NonNull;
pub trait AddRecContext:
pub trait RedBlackTreeAddingContext:
BinaryTreeRootGetter
+ BinaryTreeChildrenGetterContext
+ BinaryTreeRootRelationSetterContext
+ BinaryTreeRelationSetterContext
+ BinaryTreeDirectionDispatcherClojure
+ 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,
dir: BinaryTreeDirection,
}
struct Stack<T> {
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) {
pub fn add<Ctx: RedBlackTreeAddingContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
ctx.clearLeftChild(newNode.clone());
ctx.clearRightChild(newNode.clone());
ctx.setColor(newNode.clone(), Color::RED);
@ -125,13 +42,13 @@ pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
return;
}
Some(root) => {
link(ctx, root, newNode);
balance(ctx);
_link(&mut ctx.getLinkingContext(), root, newNode);
_balance(&mut ctx.getBalancingContext());
}
}
}
trait LinkingContext:
pub trait RedBlackTreeAddingContext_Linking:
BinaryTreeChildrenGetterContext
+ BinaryTreeRelationSetterContext
+ BinaryTreeDirectionDispatcherClojure
@ -139,7 +56,11 @@ trait LinkingContext:
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 {
let dir = ctx
.determineDirection(it.clone())
@ -166,22 +87,25 @@ fn link<Ctx: LinkingContext>(ctx: &mut Ctx, mut it: Ctx::NodeRef, newNode: Ctx::
}
}
trait BalancingContext: RedBlackTreeColorContext {
fn getLeftDirectedContext(&mut self) -> impl DirectedBalancingContext<NodeRef = Self::NodeRef>;
fn getRightDirectedContext(&mut self)
-> impl DirectedBalancingContext<NodeRef = Self::NodeRef>;
pub trait RedBlackTreeAddingContext_Balancing: RedBlackTreeColorContext {
fn getLeftDirectedContext(
&mut self,
) -> 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
{
fn rotateForward_Forward(&mut self, parent: Self::NodeRef, 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 {
let parent;
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,
grandparent: Frame<Ctx::NodeRef>,
parent: Frame<Ctx::NodeRef>,
grandparent: ParentInfo<Ctx::NodeRef>,
parent: ParentInfo<Ctx::NodeRef>,
) -> bool {
let uncle = ctx.getOppositeChild(grandparent.node.clone());
if let Some(uncle) = uncle {
@ -233,7 +157,7 @@ fn balance<Ctx: BalancingContext>(ctx: &mut Ctx) {
let normalizedParent;
if grandparent.dir != parent.dir {
normalizedParent = Frame {
normalizedParent = ParentInfo {
node: ctx.getOppositeChild(parent.node.clone()).unwrap(),
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;
mod context;
pub mod algo;
pub mod context;