Draft implementation of recursive 'add' operation
This commit is contained in:
parent
27ec357036
commit
104e3e4cd9
@ -1 +1 @@
|
||||
Subproject commit 58be1f002339ddf6d56f2c38fea830f67a59dc9c
|
||||
Subproject commit 3ce0bffc1c08ce462bc69f86c9b97d963f8e6ff0
|
||||
79
src/algo/add.kt
Normal file
79
src/algo/add.kt
Normal 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
125
src/algo/add.rs
Normal 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
1
src/algo/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
mod add;
|
||||
12
src/context.rs
Normal file
12
src/context.rs
Normal 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
4
src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
mod algo;
|
||||
mod context;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user