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