diff --git a/binary-tree-core-0 b/binary-tree-core-0 index 58be1f0..3ce0bff 160000 --- a/binary-tree-core-0 +++ b/binary-tree-core-0 @@ -1 +1 @@ -Subproject commit 58be1f002339ddf6d56f2c38fea830f67a59dc9c +Subproject commit 3ce0bffc1c08ce462bc69f86c9b97d963f8e6ff0 diff --git a/src/algo/add.kt b/src/algo/add.kt new file mode 100644 index 0000000..bf87ec0 --- /dev/null +++ b/src/algo/add.kt @@ -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) + } + } + } \ No newline at end of file diff --git a/src/algo/add.rs b/src/algo/add.rs new file mode 100644 index 0000000..bed5850 --- /dev/null +++ b/src/algo/add.rs @@ -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: &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: &mut Ctx, + grandgrandparent: Option<(Ctx::NodeRef, BinaryTreeDirection)>, + grandparent: Option<(Ctx::NodeRef, BinaryTreeDirection)>, + parent: (Ctx::NodeRef, BinaryTreeDirection), + _node: Option, + 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 + }, + } + + + } + } +} + + diff --git a/src/algo/mod.rs b/src/algo/mod.rs new file mode 100644 index 0000000..b4128ae --- /dev/null +++ b/src/algo/mod.rs @@ -0,0 +1 @@ +mod add; \ No newline at end of file diff --git a/src/context.rs b/src/context.rs new file mode 100644 index 0000000..3708f20 --- /dev/null +++ b/src/context.rs @@ -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); +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..68d7b63 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,4 @@ +mod algo; +mod context; + +