Separated context for balancing
This commit is contained in:
parent
c1a9b8a6bc
commit
2303585d5e
@ -68,8 +68,11 @@ impl<T> Stack<T> {
|
|||||||
return self._get::<1>();
|
return self._get::<1>();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getGrandGrandParent(&self) -> &T {
|
fn getGrandGrandParent(&self) -> Option<&T> {
|
||||||
return self._get::<2>();
|
match self.hasGrandGrandParent() {
|
||||||
|
false => None,
|
||||||
|
true => Some(self._get::<2>()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop(&mut self) -> T {
|
fn pop(&mut self) -> T {
|
||||||
@ -173,7 +176,23 @@ fn _add_recursive<Ctx: AddRecContext>(
|
|||||||
unsafe { balance(ctx, stack) }
|
unsafe { balance(ctx, stack) }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn balance<Ctx: AddRecContext>(ctx: &mut Ctx, stack: &mut Stack<Frame<Ctx::NodeRef>>) {
|
trait DirectedBalancingContext:
|
||||||
|
RedBlackTreeColorContext + DirectedBinaryTreeChildrenGetterContext
|
||||||
|
{
|
||||||
|
fn rotateForward_Forward(&mut self, parent: Self::NodeRef, pivot: Self::NodeRef);
|
||||||
|
fn rotateOpposite(
|
||||||
|
&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>>) {
|
||||||
loop {
|
loop {
|
||||||
if ctx.getColor(stack.getParent().node.clone()) == Color::BLACK {
|
if ctx.getColor(stack.getParent().node.clone()) == Color::BLACK {
|
||||||
break;
|
break;
|
||||||
@ -183,36 +202,57 @@ unsafe fn balance<Ctx: AddRecContext>(ctx: &mut Ctx, stack: &mut Stack<Frame<Ctx
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut symCtx =
|
match stack.getGrandParent().dir {
|
||||||
DynamicDirectedBinaryTreeContextFromContext::wrap_mut(ctx, stack.getGrandParent().dir);
|
BinaryTreeDirection::LEFT => {
|
||||||
|
if _directed(&mut ctx.getLeftDirectedContext(), stack) {
|
||||||
let uncle = symCtx.getOppositeChild(stack.getGrandParent().node.clone());
|
break;
|
||||||
if let Some(uncle) = uncle {
|
}
|
||||||
if ctx.getColor(uncle.clone()) == Color::RED {
|
}
|
||||||
ctx.setColor(stack.getParent().node.clone(), Color::BLACK);
|
BinaryTreeDirection::RIGHT => {
|
||||||
ctx.setColor(uncle, Color::BLACK);
|
if _directed(&mut ctx.getRightDirectedContext(), stack) {
|
||||||
ctx.setColor(stack.getGrandParent().node.clone(), Color::RED);
|
|
||||||
|
|
||||||
if !stack.hasGrandGrandParent() {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
stack.popDiscard();
|
|
||||||
stack.popDiscard();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if stack.getGrandParent().dir != stack.getParent().dir {
|
fn _directed<Ctx: DirectedBalancingContext>(
|
||||||
todo!("__rotateForward_Forward(parent, grandParent)");
|
ctx: &mut Ctx,
|
||||||
stack.replaceTop(Frame {
|
stack: &mut Stack<Frame<Ctx::NodeRef>>,
|
||||||
node: stack.getParent().node,
|
) -> bool {
|
||||||
dir: stack.getGrandParent().dir,
|
let uncle = ctx.getOppositeChild(stack.getGrandParent().node.clone());
|
||||||
})
|
if let Some(uncle) = uncle {
|
||||||
}
|
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(stack.getGrandParent().node.clone(), Color::RED);
|
ctx.setColor(uncle, Color::BLACK);
|
||||||
todo!("__rotateOpposite_Switch(grandParent)");
|
ctx.setColor(stack.getGrandParent().node.clone(), Color::RED);
|
||||||
|
|
||||||
break;
|
if !stack.hasGrandGrandParent() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
stack.popDiscard();
|
||||||
|
stack.popDiscard();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if stack.getGrandParent().dir != stack.getParent().dir {
|
||||||
|
ctx.rotateForward_Forward(
|
||||||
|
stack.getGrandParent().node.clone(),
|
||||||
|
stack.getParent().node.clone(),
|
||||||
|
);
|
||||||
|
stack.replaceTop(Frame {
|
||||||
|
node: stack.getParent().node.clone(),
|
||||||
|
dir: stack.getGrandParent().dir,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
ctx.setColor(stack.getParent().node.clone(), Color::BLACK);
|
||||||
|
ctx.setColor(stack.getGrandParent().node.clone(), Color::RED);
|
||||||
|
ctx.rotateOpposite(
|
||||||
|
stack.getGrandGrandParent().map(|f| (f.node.clone(), f.dir)),
|
||||||
|
stack.getGrandParent().node.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user