Non-recursive find-and-link

This commit is contained in:
Andrew Golovashevich 2025-12-29 21:07:42 +03:00
parent 1dd64086db
commit ba1a8d0533

View File

@ -112,23 +112,6 @@ impl<T> Stack<T> {
} }
} }
fn _getChildFrame<Ctx: AddRecContext>(
ctx: &mut Ctx,
node: Ctx::NodeRef,
stack: &mut Stack<Frame<Ctx::NodeRef>>,
) -> Option<Ctx::NodeRef> {
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()),
}
stack.push(Frame { node, dir });
return child;
}
pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) { pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
ctx.clearLeftChild(newNode.clone()); ctx.clearLeftChild(newNode.clone());
ctx.clearRightChild(newNode.clone()); ctx.clearRightChild(newNode.clone());
@ -142,38 +125,45 @@ pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
return; return;
} }
Some(root) => { Some(root) => {
let mut stack: Stack<Frame<Ctx::NodeRef>> = link(ctx, root, newNode);
Stack::init(&mut [const { MaybeUninit::uninit() }; usize::BITS as usize]); balance(ctx);
let child = _getChildFrame(ctx, root.clone(), &mut stack);
_add_recursive(ctx, &mut stack, child, newNode);
ctx.setColor(root, Color::BLACK)
} }
} }
} }
fn _add_recursive<Ctx: AddRecContext>( trait LinkingContext:
ctx: &mut Ctx, BinaryTreeChildrenGetterContext
stack: &mut Stack<Frame<Ctx::NodeRef>>, + BinaryTreeRelationSetterContext
nodeOrPlace: Option<Ctx::NodeRef>, + BinaryTreeDirectionDispatcherClojure
newNode: Ctx::NodeRef, {
) { fn stackAddParentInfo(&mut self, node: Self::NodeRef, dir: BinaryTreeDirection);
match nodeOrPlace { }
None => match stack.getParent().dir {
BinaryTreeDirection::LEFT => { fn link<Ctx: LinkingContext>(ctx: &mut Ctx, mut it: Ctx::NodeRef, newNode: Ctx::NodeRef) {
ctx.setLeftRelation(stack.getParent().node.clone(), newNode.clone()) loop {
let dir = ctx
.determineDirection(it.clone())
.unwrap_or(BinaryTreeDirection::LEFT);
let child;
match dir {
BinaryTreeDirection::LEFT => child = ctx.getLeftChild(it.clone()),
BinaryTreeDirection::RIGHT => child = ctx.getRightChild(it.clone()),
}
ctx.stackAddParentInfo(it.clone(), dir);
match child {
None => {
match dir {
BinaryTreeDirection::LEFT => ctx.setLeftRelation(it.clone(), newNode),
BinaryTreeDirection::RIGHT => ctx.setRightRelation(it.clone(), newNode),
}
return;
} }
BinaryTreeDirection::RIGHT => { Some(child) => {
ctx.setRightRelation(stack.getParent().node.clone(), newNode.clone()) it = child;
continue;
} }
},
Some(node) => {
let child = _getChildFrame(ctx, node, stack);
_add_recursive(ctx, stack, child, newNode);
} }
} }
unsafe { balance(ctx) }
} }
trait BalancingContext: RedBlackTreeColorContext { trait BalancingContext: RedBlackTreeColorContext {