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) {
|
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 => {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
trait BalancingContext: RedBlackTreeColorContext {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user