Draft implementation of recursive 'add' operation

This commit is contained in:
Andrew Golovashevich 2025-12-29 15:14:36 +03:00
parent 27ec357036
commit 104e3e4cd9
6 changed files with 222 additions and 1 deletions

@ -1 +1 @@
Subproject commit 58be1f002339ddf6d56f2c38fea830f67a59dc9c
Subproject commit 3ce0bffc1c08ce462bc69f86c9b97d963f8e6ff0

79
src/algo/add.kt Normal file
View File

@ -0,0 +1,79 @@
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)
}
}
}

125
src/algo/add.rs Normal file
View File

@ -0,0 +1,125 @@
use crate::context::{Color, RedBlackTreeColorContext};
use binary_tree_core_0::NodeRefContainer;
use binary_tree_core_0::base_context::{
BinaryTreeChildrenGetterContext, BinaryTreeDirection, BinaryTreeDirectionDispatcherClojure,
BinaryTreeRootGetter,
};
use binary_tree_core_0::directed_context::{DirectedBinaryTreeChildrenGetterContext, DynamicDirectedBinaryTreeContextFromContext};
use binary_tree_core_0::relation_context::{
BinaryTreeRelationSetterContext, BinaryTreeRootRelationSetterContext,
};
pub trait AddRecContext:
BinaryTreeRootGetter
+ BinaryTreeChildrenGetterContext
+ BinaryTreeRootRelationSetterContext
+ BinaryTreeRelationSetterContext
+ BinaryTreeDirectionDispatcherClojure
+ RedBlackTreeColorContext
{
}
pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
ctx.clearLeftChild(newNode.clone());
ctx.clearRightChild(newNode.clone());
ctx.setColor(newNode.clone(), Color::RED);
let node = ctx.getRoot();
match node {
None => {
ctx.setColor(newNode.clone(), Color::BLACK);
ctx.setRootRelation(newNode);
return;
}
Some(node) => {
let dir = ctx
.determineDirection(node.clone())
.unwrap_or(BinaryTreeDirection::LEFT);
let child;
match dir {
BinaryTreeDirection::LEFT => child = ctx.getLeftChild(node.clone()),
BinaryTreeDirection::RIGHT => child = ctx.getRightChild(node.clone()),
}
_add_recursive(ctx, None, None, (node.clone(), dir), child, newNode);
ctx.setColor(node, Color::BLACK)
}
}
}
fn _add_recursive<Ctx: AddRecContext>(
ctx: &mut Ctx,
grandgrandparent: Option<(Ctx::NodeRef, BinaryTreeDirection)>,
grandparent: Option<(Ctx::NodeRef, BinaryTreeDirection)>,
parent: (Ctx::NodeRef, BinaryTreeDirection),
_node: Option<Ctx::NodeRef>,
newNode: Ctx::NodeRef,
) {
let node;
match _node {
None => {
match parent.1 {
BinaryTreeDirection::LEFT => ctx.setLeftRelation(parent.0.clone(), newNode.clone()),
BinaryTreeDirection::RIGHT => {
ctx.setRightRelation(parent.0.clone(), newNode.clone())
}
}
node = newNode;
}
Some(_node) => {
node = _node;
let childDir = ctx
.determineDirection(node.clone())
.unwrap_or(BinaryTreeDirection::LEFT);
let child;
match childDir {
BinaryTreeDirection::LEFT => child = ctx.getLeftChild(node.clone()),
BinaryTreeDirection::RIGHT => child = ctx.getRightChild(node.clone()),
}
_add_recursive(
ctx,
grandparent.clone(),
Some(parent.clone()),
(node.clone(), childDir),
child,
newNode,
);
}
}
if ctx.getColor(parent.0.clone()) == Color::BLACK {
return; // todo break
}
match grandparent {
None => {
ctx.setColor(parent.0, Color::BLACK);
return; // todo break
}
Some(grandparent) => {
let mut symCtx = DynamicDirectedBinaryTreeContextFromContext::wrap_mut(ctx, grandparent.1);
let uncle = symCtx.getOppositeChild(grandparent.0.clone());
if let Some(uncle) = uncle {
if ctx.getColor(uncle.clone()) == Color::RED {
ctx.setColor(parent.0, Color::BLACK);
ctx.setColor(uncle, Color::BLACK);
ctx.setColor(grandparent.0, Color::RED);
return; // todo current = grandparent
}
}
match grandparent.1 == parent.1 {
true => {
todo!("__rotateOpposite_Switch(grandParent)");
return; // todo continue
},
false => {
todo!("__rotateForward_Forward(parent, grandParent)");
return; // todo current = parent
},
}
}
}
}

1
src/algo/mod.rs Normal file
View File

@ -0,0 +1 @@
mod add;

12
src/context.rs Normal file
View File

@ -0,0 +1,12 @@
use binary_tree_core_0::NodeRefContainer;
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Color {
BLACK,
RED,
}
pub trait RedBlackTreeColorContext: NodeRefContainer {
fn getColor(&self, node: Self::NodeRef) -> Color;
fn setColor(&self, node: Self::NodeRef, color: Color);
}

4
src/lib.rs Normal file
View File

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