Cleaning up 'add' algorithm, naming and publishing
This commit is contained in:
parent
ba1a8d0533
commit
e6fb9bf061
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
153
src/algo/add.rs
153
src/algo/add.rs
@ -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)
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
mod add;
|
||||
pub mod add;
|
||||
@ -1,4 +1,4 @@
|
||||
mod algo;
|
||||
mod context;
|
||||
pub mod algo;
|
||||
pub mod context;
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user