Non-recursive find-and-link
This commit is contained in:
parent
1dd64086db
commit
ba1a8d0533
@ -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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user