Fixed balancing algorithm bugs and extracted it to separate non-recursive function

This commit is contained in:
Andrew Golovashevich 2025-12-29 20:20:38 +03:00
parent f349a8751b
commit c1a9b8a6bc

View File

@ -170,36 +170,49 @@ fn _add_recursive<Ctx: AddRecContext>(
} }
} }
unsafe { balance(ctx, stack) }
}
unsafe fn balance<Ctx: AddRecContext>(ctx: &mut Ctx, stack: &mut Stack<Frame<Ctx::NodeRef>>) {
loop {
if ctx.getColor(stack.getParent().node.clone()) == Color::BLACK { if ctx.getColor(stack.getParent().node.clone()) == Color::BLACK {
return; // todo break break;
} }
if !stack.hasGrandParent() { if !stack.hasGrandParent() {
ctx.setColor(stack.getParent().node.clone(), Color::BLACK); ctx.setColor(stack.getParent().node.clone(), Color::BLACK);
return; // todo break break;
} }
let mut symCtx = let mut symCtx =
DynamicDirectedBinaryTreeContextFromContext::wrap_mut(ctx, stack.getGrandParent().dir); DynamicDirectedBinaryTreeContextFromContext::wrap_mut(ctx, stack.getGrandParent().dir);
let uncle = symCtx.getOppositeChild(stack.getGrandParent().node.clone()); let uncle = symCtx.getOppositeChild(stack.getGrandParent().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(stack.getParent().node.clone(), Color::BLACK);
ctx.setColor(uncle, Color::BLACK); ctx.setColor(uncle, Color::BLACK);
ctx.setColor(stack.getGrandParent().node.clone(), Color::RED); ctx.setColor(stack.getGrandParent().node.clone(), Color::RED);
return; // todo current = grandparent
if !stack.hasGrandGrandParent() {
break;
}
stack.popDiscard();
stack.popDiscard();
continue;
} }
} }
match stack.getGrandParent().dir == stack.getParent().dir { if stack.getGrandParent().dir != stack.getParent().dir {
true => {
todo!("__rotateOpposite_Switch(grandParent)");
stack.replaceTop(stack.pop());
return; // todo continue
}
false => {
todo!("__rotateForward_Forward(parent, grandParent)"); todo!("__rotateForward_Forward(parent, grandParent)");
stack.popDiscard(); stack.replaceTop(Frame {
return; // todo current = parent node: stack.getParent().node,
} dir: stack.getGrandParent().dir,
})
}
ctx.setColor(stack.getParent().node.clone(), Color::BLACK);
ctx.setColor(stack.getGrandParent().node.clone(), Color::RED);
todo!("__rotateOpposite_Switch(grandParent)");
break;
} }
} }