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