Redesigned balancing without explicit using stack

This commit is contained in:
Andrew Golovashevich 2025-12-29 20:57:25 +03:00
parent 2303585d5e
commit 1dd64086db

View File

@ -173,43 +173,53 @@ fn _add_recursive<Ctx: AddRecContext>(
} }
} }
unsafe { balance(ctx, stack) } unsafe { balance(ctx) }
}
trait BalancingContext: RedBlackTreeColorContext {
fn getLeftDirectedContext(&mut self) -> impl DirectedBalancingContext<NodeRef = Self::NodeRef>;
fn getRightDirectedContext(&mut self)
-> impl DirectedBalancingContext<NodeRef = Self::NodeRef>;
fn stackPopParentInfo(&self) -> Option<Frame<Self::NodeRef>>;
} }
trait DirectedBalancingContext: trait DirectedBalancingContext:
RedBlackTreeColorContext + DirectedBinaryTreeChildrenGetterContext RedBlackTreeColorContext + DirectedBinaryTreeChildrenGetterContext
{ {
fn rotateForward_Forward(&mut self, parent: Self::NodeRef, pivot: Self::NodeRef); fn rotateForward_Forward(&mut self, parent: Self::NodeRef, pivot: Self::NodeRef);
fn rotateOpposite( fn rotateOpposite_GrandParent(&mut self, pivot: Self::NodeRef);
&mut self,
parent: Option<(Self::NodeRef, BinaryTreeDirection)>,
pivot: Self::NodeRef,
);
}
trait BalancingContext: RedBlackTreeColorContext {
fn getLeftDirectedContext(&mut self) -> impl DirectedBalancingContext<NodeRef = Self::NodeRef>;
fn getRightDirectedContext(&mut self)
-> impl DirectedBalancingContext<NodeRef = Self::NodeRef>;
} }
unsafe fn balance<Ctx: BalancingContext>(ctx: &mut Ctx, stack: &mut Stack<Frame<Ctx::NodeRef>>) { fn balance<Ctx: BalancingContext>(ctx: &mut Ctx) {
loop { loop {
if ctx.getColor(stack.getParent().node.clone()) == Color::BLACK { let parent;
break; match ctx.stackPopParentInfo() {
None => return,
Some(_parent) => parent = _parent,
} }
if !stack.hasGrandParent() {
ctx.setColor(stack.getParent().node.clone(), Color::BLACK); if ctx.getColor(parent.node.clone()) == Color::BLACK {
break; break;
} }
match stack.getGrandParent().dir { let grandparent;
match ctx.stackPopParentInfo() {
None => {
ctx.setColor(parent.node.clone(), Color::BLACK);
break;
}
Some(_grandparent) => grandparent = _grandparent,
}
match grandparent.dir {
BinaryTreeDirection::LEFT => { BinaryTreeDirection::LEFT => {
if _directed(&mut ctx.getLeftDirectedContext(), stack) { if _directed(&mut ctx.getLeftDirectedContext(), grandparent, parent) {
break; break;
} }
} }
BinaryTreeDirection::RIGHT => { BinaryTreeDirection::RIGHT => {
if _directed(&mut ctx.getRightDirectedContext(), stack) { if _directed(&mut ctx.getRightDirectedContext(), grandparent, parent) {
break; break;
} }
} }
@ -217,40 +227,34 @@ unsafe fn balance<Ctx: BalancingContext>(ctx: &mut Ctx, stack: &mut Stack<Frame<
fn _directed<Ctx: DirectedBalancingContext>( fn _directed<Ctx: DirectedBalancingContext>(
ctx: &mut Ctx, ctx: &mut Ctx,
stack: &mut Stack<Frame<Ctx::NodeRef>>, grandparent: Frame<Ctx::NodeRef>,
parent: Frame<Ctx::NodeRef>,
) -> bool { ) -> bool {
let uncle = ctx.getOppositeChild(stack.getGrandParent().node.clone()); let uncle = ctx.getOppositeChild(grandparent.node.clone());
if let Some(uncle) = uncle { if let Some(uncle) = uncle {
if ctx.getColor(uncle.clone()) == Color::RED { if ctx.getColor(uncle.clone()) == Color::RED {
ctx.setColor(stack.getParent().node.clone(), Color::BLACK); ctx.setColor(parent.node.clone(), Color::BLACK);
ctx.setColor(uncle, Color::BLACK); ctx.setColor(uncle, Color::BLACK);
ctx.setColor(stack.getGrandParent().node.clone(), Color::RED); ctx.setColor(grandparent.node.clone(), Color::RED);
if !stack.hasGrandGrandParent() {
return true;
}
stack.popDiscard();
stack.popDiscard();
return false; return false;
} }
} }
if stack.getGrandParent().dir != stack.getParent().dir { let normalizedParent;
ctx.rotateForward_Forward( if grandparent.dir != parent.dir {
stack.getGrandParent().node.clone(), normalizedParent = Frame {
stack.getParent().node.clone(), node: ctx.getOppositeChild(parent.node.clone()).unwrap(),
); dir: grandparent.dir,
stack.replaceTop(Frame { };
node: stack.getParent().node.clone(), ctx.rotateForward_Forward(grandparent.node.clone(), parent.node.clone());
dir: stack.getGrandParent().dir, let _ = parent;
}) } else {
normalizedParent = parent;
} }
ctx.setColor(stack.getParent().node.clone(), Color::BLACK); ctx.setColor(normalizedParent.node.clone(), Color::BLACK);
ctx.setColor(stack.getGrandParent().node.clone(), Color::RED); ctx.setColor(grandparent.node.clone(), Color::RED);
ctx.rotateOpposite( ctx.rotateOpposite_GrandParent(grandparent.node.clone());
stack.getGrandGrandParent().map(|f| (f.node.clone(), f.dir)),
stack.getGrandParent().node.clone(),
);
return true; return true;
} }