pub(crate) type Link<T> = Option<Box<AVLNode<T>>>;
#[derive(Debug)]
pub struct AVLNode<T> {
pub(crate) value: T,
pub(crate) left: Link<T>,
pub(crate) right: Link<T>,
pub(crate) height: usize,
}
impl<T> AVLNode<T> {
pub(crate) fn new(value: T) -> Self {
Self {
value,
left: None,
right: None,
height: 1,
}
}
pub fn value(&self) -> &T {
&self.value
}
pub fn height(&self) -> usize {
self.height
}
pub fn left(&self) -> Option<&Self> {
self.left.as_deref()
}
pub fn right(&self) -> Option<&Self> {
self.right.as_deref()
}
}
pub(crate) fn height<T>(node: &Link<T>) -> usize {
node.as_deref().map_or(0, |node| node.height)
}
fn update_height<T>(node: &mut AVLNode<T>) {
node.height = 1 + height(&node.left).max(height(&node.right));
}
fn balance_factor<T>(node: &AVLNode<T>) -> isize {
height(&node.left) as isize - height(&node.right) as isize
}
fn rotate_right<T>(mut y: Box<AVLNode<T>>) -> Box<AVLNode<T>> {
let mut x = y.left.take().expect("right rotation requires a left child");
let middle = x.right.take();
y.left = middle;
update_height(&mut y);
x.right = Some(y);
update_height(&mut x);
x
}
fn rotate_left<T>(mut x: Box<AVLNode<T>>) -> Box<AVLNode<T>> {
let mut y = x
.right
.take()
.expect("left rotation requires a right child");
let middle = y.left.take();
x.right = middle;
update_height(&mut x);
y.left = Some(x);
update_height(&mut y);
y
}
pub(crate) fn rebalance<T>(mut node: Box<AVLNode<T>>) -> Box<AVLNode<T>> {
update_height(&mut node);
let balance = balance_factor(&node);
if balance > 1 {
if node
.left
.as_deref()
.is_some_and(|left| balance_factor(left) < 0)
{
node.left = node.left.take().map(rotate_left);
}
return rotate_right(node);
}
if balance < -1 {
if node
.right
.as_deref()
.is_some_and(|right| balance_factor(right) > 0)
{
node.right = node.right.take().map(rotate_right);
}
return rotate_left(node);
}
node
}