flow::binary::avl

This commit is contained in:
AF 2023-06-16 09:40:35 +00:00
parent 0cd31fa376
commit 711221e4d8
5 changed files with 94 additions and 84 deletions

View File

@ -1,3 +1,4 @@
pub mod avl;
pub mod bounds; pub mod bounds;
use crate::flow::comparator::*; use crate::flow::comparator::*;
@ -125,82 +126,3 @@ pub trait BinaryTreesMutable<'a>: BinaryTreesEmpty<'a> {
}) })
} }
} }
pub trait BinaryTreesAvl<'a>: BinaryTrees<'a> {
fn height(&self, tree: &Self::Tree) -> u64;
fn leaf_height_error<T: 'a>(&self, height: u64) -> BTWrap<'a, Self, T>;
fn assume_node(&self, tree: &Self::Tree) -> BTWrap<'a, Self, Self::Node> {
match self.refer(tree) {
Some(reference) => self.resolve(&reference),
None => self.leaf_height_error(self.height(tree)),
}
}
fn join_key_unbalanced(
&self,
tl: Self::Tree,
key: Self::Key,
tr: Self::Tree,
) -> BTWrap<'a, Self, Self::Node>;
fn join_key_balanced_tree(
&self,
tl: Self::Tree,
key: Self::Key,
tr: Self::Tree,
) -> BTWrap<'a, Self, Self::Tree> {
self.clone()
.tree_bind(self.clone().join_key_balanced(tl, key, tr))
}
fn join_key_balanced(
self,
tl: Self::Tree,
key: Self::Key,
tr: Self::Tree,
) -> BTWrap<'a, Self, Self::Node> {
let (hl, hr) = (self.height(&tl), self.height(&tr));
match (hl.saturating_sub(hr), hr.saturating_sub(hl)) {
(0, 0) | (0, 1) | (1, 0) => self.join_key_unbalanced(tl, key, tr),
(0, _) => Self::bind(self.assume_node(&tr), move |nr| {
let (trl, trr, kr) = self.split(&nr);
let (rlh, rrh) = (self.height(&trl), self.height(&trr));
if rlh > rrh {
Self::bind(self.assume_node(&trl), move |nrl| {
let (trll, trlr, krl) = self.split(&nrl);
Self::T::bind2(
self.join_key_balanced_tree(tl, key, trll),
self.join_key_balanced_tree(trlr, kr, trr),
|ti, to| self.join_key_balanced(ti, krl, to),
)
})
} else {
Self::bind(self.join_key_balanced_tree(tl, key, trl), |t| {
self.join_key_balanced(t, kr, trr)
})
}
}),
(_, 0) => Self::bind(self.assume_node(&tl), move |nl| {
let (tll, tlr, kl) = self.split(&nl);
let (hll, hlr) = (self.height(&tll), self.height(&tlr));
if hll < hlr {
Self::bind(self.assume_node(&tlr), move |nlr| {
let (tlrl, tlrr, klr) = self.split(&nlr);
Self::T::bind2(
self.join_key_balanced_tree(tll, kl, tlrl),
self.join_key_balanced_tree(tlrr, key, tr),
|to, ti| self.join_key_balanced(to, klr, ti),
)
})
} else {
Self::bind(self.join_key_balanced_tree(tlr, key, tr), |t| {
self.join_key_balanced(tll, kl, t)
})
}
}),
(_, _) => unreachable!(),
}
}
}

80
src/flow/binary/avl.rs Normal file
View File

@ -0,0 +1,80 @@
use super::*;
pub trait BinaryTreesAvl<'a>: BinaryTrees<'a> {
fn height(&self, tree: &Self::Tree) -> u64;
fn leaf_height_error<T: 'a>(&self, height: u64) -> BTWrap<'a, Self, T>;
fn assume_node(&self, tree: &Self::Tree) -> BTWrap<'a, Self, Self::Node> {
match self.refer(tree) {
Some(reference) => self.resolve(&reference),
None => self.leaf_height_error(self.height(tree)),
}
}
fn join_key_unbalanced(
&self,
tl: Self::Tree,
key: Self::Key,
tr: Self::Tree,
) -> BTWrap<'a, Self, Self::Node>;
fn join_key_balanced_tree(
&self,
tl: Self::Tree,
key: Self::Key,
tr: Self::Tree,
) -> BTWrap<'a, Self, Self::Tree> {
self.clone()
.tree_bind(self.clone().join_key_balanced(tl, key, tr))
}
fn join_key_balanced(
self,
tl: Self::Tree,
key: Self::Key,
tr: Self::Tree,
) -> BTWrap<'a, Self, Self::Node> {
let (hl, hr) = (self.height(&tl), self.height(&tr));
match (hl.saturating_sub(hr), hr.saturating_sub(hl)) {
(0, 0) | (0, 1) | (1, 0) => self.join_key_unbalanced(tl, key, tr),
(0, _) => Self::bind(self.assume_node(&tr), move |nr| {
let (trl, trr, kr) = self.split(&nr);
let (rlh, rrh) = (self.height(&trl), self.height(&trr));
if rlh > rrh {
Self::bind(self.assume_node(&trl), move |nrl| {
let (trll, trlr, krl) = self.split(&nrl);
Self::T::bind2(
self.join_key_balanced_tree(tl, key, trll),
self.join_key_balanced_tree(trlr, kr, trr),
|ti, to| self.join_key_balanced(ti, krl, to),
)
})
} else {
Self::bind(self.join_key_balanced_tree(tl, key, trl), |t| {
self.join_key_balanced(t, kr, trr)
})
}
}),
(_, 0) => Self::bind(self.assume_node(&tl), move |nl| {
let (tll, tlr, kl) = self.split(&nl);
let (hll, hlr) = (self.height(&tll), self.height(&tlr));
if hll < hlr {
Self::bind(self.assume_node(&tlr), move |nlr| {
let (tlrl, tlrr, klr) = self.split(&nlr);
Self::T::bind2(
self.join_key_balanced_tree(tll, kl, tlrl),
self.join_key_balanced_tree(tlrr, key, tr),
|to, ti| self.join_key_balanced(to, klr, ti),
)
})
} else {
Self::bind(self.join_key_balanced_tree(tlr, key, tr), |t| {
self.join_key_balanced(tll, kl, t)
})
}
}),
(_, _) => unreachable!(),
}
}
}

View File

@ -1,4 +1,7 @@
use crate::{flow::binary::*, func::context::*}; use crate::{
flow::binary::{avl::*, *},
func::context::*,
};
use super::*; use super::*;

View File

@ -1,6 +1,9 @@
use std::{fmt::Display, marker::PhantomData, rc::Rc}; use std::{fmt::Display, marker::PhantomData, rc::Rc};
use crate::flow::{binary::*, comparator::*}; use crate::flow::{
binary::{avl::*, *},
comparator::*,
};
use crate::func::{context::*, *}; use crate::func::{context::*, *};
#[derive(Clone)] #[derive(Clone)]

View File

@ -1,6 +1,8 @@
use crate::flow::{binary::*, comparator::*}; use crate::flow::{
use crate::func::context::*; binary::{avl::BinaryTreesAvl, *},
use crate::func::*; comparator::*,
};
use crate::func::{context::*, *};
use crate::rstd::fallible::*; use crate::rstd::fallible::*;
use super::{bounds::*, *}; use super::{bounds::*, *};